From f39e37002b2ffe8c6aa65bd4942c91483d8e9fc9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 29 Apr 2025 16:40:58 -0400 Subject: [PATCH 01/19] [deps] Autofill: Update prettier to v3.5.3 (#14480) * [deps] Autofill: Update prettier to v3.5.3 * prettier formatting updates --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jonathan Prusik --- .../src/autofill/shared/styles/webfonts.scss | 160 ++++++++++-------- apps/web/src/scss/variables.scss | 5 +- libs/components/src/variables.scss | 5 +- package-lock.json | 8 +- package.json | 2 +- 5 files changed, 98 insertions(+), 82 deletions(-) diff --git a/apps/browser/src/autofill/shared/styles/webfonts.scss b/apps/browser/src/autofill/shared/styles/webfonts.scss index 6433060c534..20d0eda0622 100644 --- a/apps/browser/src/autofill/shared/styles/webfonts.scss +++ b/apps/browser/src/autofill/shared/styles/webfonts.scss @@ -62,14 +62,15 @@ font-display: swap; src: url(data:font/woff2;base64,d09GMgABAAAAADGUAA8AAAAAWcgAADE0AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGk4biAQchgQGYD9TVEFUXgCCFBEQCoGEFOwQC4NUAAE2AiQDhyQEIAWEeAeKDxvsSgXs2CNuB0E1028e2f/n4+RwRQ3Aj0I7zJzR+mjYZ7Q1O65tzIk+N0mKDb8rohtmCjPZIq/+LLvCoVLjPmB0ncMcKu4qtugRG/pALzo4t2PA35oEX1KJqv4ISWYhpG+rr6TTjQ3cMrCOnbl8mz5xlxmCbXY6e7qwpo1K2DNqJkqIgkgKBhioYGIHKFbgjJ5iTpvNpTVXFf/7XBBff/Rvz8yZ++hnAUrQIrJRgL5YFFMBj+CyXX/Pmh8e5xycTkzS0vpKLGs2eLNHqW2/8z+AxoHU3g/b2gfPrZI8GuMkTafbiZjbfY5DQQxTMNSBLkwxzODH+bUtlLCQwbqmBODwMH6mtzD/pa1twBPMrTONICLlP2zXQdGIT09Jl9tg6vc5/XcGULqzC+KrctW46HNFkvRSUHAKLNPA/67Ar3OMUe/Y/zuXBbozqnIM6gAhTekXkuKA1OT0PT8jZ+SGbVvWjCpoK8bZuq4U7PCvCgXb/9m0Sqv6u3e7De9ZM5zZixgk9gJnG4RAQdRdvxqqv+RxC2a33UZpSZ4FSUPUWpSX0DMHxJk1S2g40BwARIDhRRdkl1J0QXpxuu/SiwCDOCN/7zt/F0g6cZaTGrWUyefTe1mz/wOx2Bb3xuNRtj9iDDFEmCZ3hT3vdRGUhuU3r4AgQBpFeNxZACVFDxMJM7DIsJM8MuxtiAz3OEmWh20w0jbOGbKMsYK82Fpuph61/ZG34vkMd0W/tWjF2BOymhTZDxs0tIGIHvfQ/Jz0pnfcKwD9qRzXQ1Ii0ETIFhPu1Gnn76UdqWJUtGiSRZJfe5YM+I/J/NfuLTIQ6vCAkEbcShFk3DhEeCYZppeICEdZYRWG9c4hsdsyU62s9BDcdHMNbXA7i2wXfA+TJBKjgIwkHJydJ/TLHo7qUX/rG7u5a1vQJZ3XGZ3c8R3VYU1rYuParz3ZRT8bdmzJUDZiHVZnVQ2K/M1/8qd6U8/qQd2qK3Uu8s0nO1GHa6GmS1KD1V3tZjaNJaqKKqqcbq60Smyge1LtxvZkWsWKHyx2LBGzXaAVBVnWqrKsCIUtZLmTE9mSOZmSAWk3re0iFTH+Zwv+gW/woQ57VRJP3HPDpWK1NsQ1Cy51+xCv1EGC0z7okM+17zt0S/ocmnE0O7Q/7J3qEZqQ1trKnJ7CBN9BR2rj0aYc0Klo054yo0YgTdqQDv0GRsJW2E47nUShnApoLeSE5uRfSA0NsMFXeYd8SLsAXABbaVcOeGpIQxlM/zGZiukmQagWzcxoNI3m53R1DWNpWQ4TtUUd7ibanMO3NDyDmbCndnDO1Spw2tmGdAjRmGnNOamD9mvOTQJtbYfuRB/SIIIT+WGxLN67AdADJ/L0a4q14mtqoG0TxH6WDc7DRGWCFy0c/1/6K2sGff/wD3/671MScul2q8x0yQ1VUNzrlSd1VKPaaXLqyI1TV6eFkYKLhxcxnKRohrKUg95Vkqm/6E9GCEA7KfikoP5gbduwHzC7Cn767ub/PRLqM193hDCTDLAQQwbFHmNXm2lf6kfM8g9DzHgCdREkpjICyIGBguP5tBsaNpnHNoLmPjOE6oLMKXfSCWXAz/AoRacTYeMCMYxYrKJRm809vdS0iVF9H1kWO3ZMLXC0d66TtsXBTmS9BDLIKhn+OCQ+VrD4VQ9d2vRjrTV6J90PFKqVXrI45vHAILvBsvtp15HOK3oMmdT7XnOZcqncHCff7xvvWnZHKz3DO72kolhZKWDVmlWbTuH8zndWpdYAV9TP7sCGg31jRUrS7hGnySByNtT2HwH8cLkIcPbGV31lh2613PhA4BGg0fyyzX53blkFen6NG/6NA+n/vTpALgDA5qwUoMEQJahcPekAusf72SMDe3zqM8DP+czFAN+oRaiOqKhUgW25dJucaOq9KYG4A+tzpp5gkk3KBJogWSD3Nc2zv0Fjps277e/AbS7tLpqJOTtX59bbuGDT0NRNq0W7GCwmi+PiZdqaTrDv/xs4+zeOL+tS7qQ5MPN66F/C+Hu1Sr7fT+76PXZX7vJtv9nfzZ9rP578ePzjzo+XP54+SXPAoE77XX/UrEG5OET4vQYyPIsFF0WiPKlIL+/RV/+rXlYmRvzRqD6Z8uDUJ/lIy4vv8DikQTeYo5bchseHcMMr+fykiitICtYF4aZx6tS17+NUchV0SiBvmrLGq+SqXglPhMvgVF5LvXIoPCnZEylFJfFS6vKeuUrekQRuEP0bwTTrqJpVBBYrR5FFUa9M1YqVq+YsjxdmdLWV3Zau2PAdR6tgyQ9FyizVUL8XSrlSotLIVKJsN5WLXaGtqVwt2+q7ErtY0y1VOZu2dMrytWyPGfVynVj3Vqi+qBZVQ8w7lesWXdM+9ntmpUYpXOCDh6tGwaLOw8RU+BEo1aoXKuQs9p1mli71E+XazuD9Xm/tNoeeKaaKl+rZ7+SIyrV7E0XM7iJn1ruIVS3Tqaq1JpTLZeqRnqlOUIO+qtbNyBBtomLFynbULjstRM6Jv57dKSopG4uOUIO3wi3sRHo8LSyZAvMOth1ShFT2Z7ieN9L8L5WfNyfW2BkWgkqmmCcEXSrJR8iaQWXm/wMLNTJ4CsGcVe3rWdHtf6uwhG7T052gquO/beSfXET2B1jkKdNfZXQkXByeM9WRpjrHc5nYbfLr+YkD1PFZYZNefHV4kjifGWRN71It/x5axuIw3ZsmsyKbH+T7M7VkPPiGrS+Hl/0D67Su78TM2VKOEyocax16wl6CTC0+++uogBA7Z+ItnqIxauyyX9h3JNmpTF7x6blSgl6U2d9mF11ZveIRRbohatqfQ2zl8MeJgxuXZ7EdypojPPghq/TF+PShXTZeQcVCO+5E1qQh240oLN734krM4kZ6r4exlLebLo91Lax3OepsRy9Sxxwrtaeo3aQG2jbkRx/1rS4XQi2IBS7s1VjETfzu+IwZvHI8Sl7tbegc+afQSDeG1kl9TNnRRW3FSqVTJW1Vc8scnfYuOeJIkAh7uRsV3Ng/xIywdlS6sr94pETWpB/evg0p+Da0gA6iL837v4F/BMRm/hxuC46fhQVU3Gr2kCjtEdiUQu3ZB3TsLGKj9okl+SDYWaQ0hBZ+RzcgHv2rhHX4Oir+PEvTmMNQzv5jxxpT6EUUBpFFzYMxtQGvQ1DfjuCF9/pG0RsHKkG8IiquaFXEzw7V7q9dw8bjjqTVuhTNqdz2tFlEcYVH6UEfIrIsBkY+jlIxue+TGzwmYgNxEVzgKHmQvZRyQkTs8voIoPsI9G+/Irz9pT9pW0e6JnnlEivzFImU2NDmAyOkN4YqcfDsW6mdH/1areEJo/3lVXf/sYE08nbGgZaoxL1JL/NxztbrXf+x0/hJ555aRRl09iguRly23mFPP1G+TrBaYL2S5VoWd+pkGaBXBYGshkY6FN9sQk2ls+pQpanGsHVmdyxntVq4McfPr9LrJHwkojJWvjZAhi98Ztr3am7Sq7eT+FfL1KuRIcNTsZHmXEygy2F6UbVh3+3G+pOfRsFeGB+kHxCKKfBSdsknq5WHxHxxyPAGrH4N5YkDEfVpFP5ro6ZIBO9IRhtsa/oYgHNuYg0kJSB77Fk581Hl9mHdxUOhpeRVR9yq8AOgHnjCMQvvFc1luII+stcDeab0tXCBTaYXtOYVQHWI0by7QH3m7ZU1t2mz5osJNpKh+DgeEG1Z7IuY6WWXn8rREqvEY2V3d9OuQ7l1ux4ZSXpKK1tSz+LtccNJIsKt9teGiJ2swodnc6rCowQP+hJ721Dt3SQdWHPkN87GUqVGSpzIxa0KU8yDkS9MAk99D5DQiAs4BIlHPLLOYedieuZB/EV74DwXsmSCmjg0upGeBD4x2LPR35Y95MrTNrtS6s5/QwM8AHwr3H4SWXkY/N2e9qh6HPY6+2wcn1YscXIEPWtvyg4QLfdBKrn6PHYUFmWjm/sc+KMWcDRHDAI6z7xXP2oG3jkIzxmY7s0bPhwTocwsamtz1jfseIz/RgGRiSfpizRgv3T94wMXH/Y0VNlrRgb4QzxhGhjZ+St+xveqb4DNSdIH02pcrX9eDOCPSzhWTTOmachJavlQ9necWN3drY9kOkReFnjsd//dOip14UEaU0JTrWofvaZ5mv7CviTJDjU9Ok5OjrLTk/x4l2NH/xDXGRoXaoV7fhKPxHMPNnNi0s//myb+wBD4c7tqdbI8Pj25EAqO3PLF/H/l8facoxQ6qDq6wOqqt0RZj8DWlEohu0eIuzkwWyfELuRI9z4mOnHQ0AmvVxwL2yIVLRedRURK/35K4UoFcOgXDlPw/gn7ee2PeUzouWrswb/O+WJL8UD6ywFNE0UK2bY5CqJ+lJ1wBEw/7BwfB1QQXVvJ4y6XR8zOv9iafjLd07kKy2IKJB+/6i/9LgugTQi4N+hPAnG6LBRXKOZM5TnoVLur3lV3vuFJmpp/LRlW7u6jwM9NmofmW+NHSUHExcCVEp/b3OVIBvdMYt6II/onpFIcTjzECIX6UJQOEYznZ4z+Ls+G/0Vsw1T0f8Jk68Wf4gCanbZmXsDP92+t6Y2Ve7R9P3ZPTXWzx0SUhn8gFyPZfnUcxMSeZIpP85mJo2JonhEGMVTMdhFCyf/WYFiEp8CxyPTS2AYTQlBfoqmM1plRWPdXDmPg/TlrcVNqUnC/HkyTDaiZa3+FJZMckAQTgKF3iojJzDRcH4LxsKyWzi+/+IPpQHK9pj8BTJ6GPfiSgv205Nq5wPGppmtZTN/ko+j6xfTM/LpGzxbQGd5GJyFeoWPFzr2OpFx0G9KzqrtkxgW+seU8QRdyp86VWmUBXT+UETF/Eiqg0MSR0txKDzeZrjce4o/t5tv5HZowTTv7pmM3Za14oh4qY4pfj7Jfge22Sqk98gh2iBXtrWRH6cOpE6omLw00ppW1VEjPLY2jxtXANJkRH8FSWGT5lyeKVmtZLrL1aqEgsOG1BGK4cf4DqCiUTPL8am5xZRv/yjg9WXDtXNfeki7jOkni9pPa1/npD85Xapfm/aV+TeCI1SghPFjP3cmFoPvD7vJ1QvZx4kBefFO01EjbfO3PKGsU1rd7JOgOyXWGczdGe4SxRAa0GgQUjZeCdRcebTQi5fW9iQe0YTq+eG/Se2le4+4MXnnjP2mmbHtRufyXrwDGTjmwExre3A7tGd+sui8PxWuwGMkk0B3DxDx+8GKUQg4kUyLJWXaiCDcANwBpCZnoZZHgzeAPi3TpTZu4tevn7Lci5vRCn94MHpew6Iaxm2cWv4/6nPiniRanyL6AnFW7ScSi3B0d0O5YDNrbwRHlDTSWpbCdCdCdptBqRuCFqkRS9UudaLPV2ye2J88KibMKpcZ+VO1iG8pyzYY5MsH3o3Kx/RrN3pdqD+RzrmXIXDHzNRhGG9/ey5M5XAmdZtNrYuKjmmfJ2fIHC6YSZWfNA40da1F6fbBghWUhfIkRXs5tvbmwqn4vtWB7HpvoZuuf4BS2J/9ydaBcnI1DgKOHNTHWBeh8P9/R/enePfG3nubOb6cWWj515JDx4xMT+CkyjTw1MU6acGqOcViWtup4opO4x8fvHrNl/7e795o/7c/lY3zSGJ/6Th0H8O8Xk3sDaXWcivHF8gBxDR8zvidm3Lgy9iGeCjV6ujT3XytzwS6z/mJ42nx5YtD+pmyO63NqomNBYGxYgwQv07Y9yDqV4Z5CzO6rF4hOhPr5aMtZbZ6PTSeQS/FBRei0MkYwL3o0f2AA2W4C6SM0icsfaD7ecvn7INKlzJhd2heXK9RDegBlhzGkp0A/PqcvsqTMBOkyeMDXo8wsqmQgvkAAQXoDc6kmrL42Q3cmH/4Heoi5xBnljDG/onPh+jOCDHg9MN/Q7hX1jteMp39vmKwByR+3duNcRpESCK5IMxgxB5lW9gfk++1f2oGYi0W52zti3LEYjLejPcob2IilpvLSEVMtKfBbeLjgvCdz7VBs+YEb8zzSp3ds0vWlmdGbC1yS/ZUPF7x21lalp9cKvXdePOu1o0aUmVkj8twBLg+regCaLBb6OSJNIgxJq7OrBWYn6qrqk1Pap4IksUWtFXkJQ/40Xya/WYTvtQqt3mAlHszLCt8aXU9N9vJUfA+8b0TH4Juqw8J3Kx3UmllsLc3Z+DP1ZNYmNNSyN8z6pkPsmfn+2siYrMMuFa2NbbmjmJASBr8tr5RYasx3zaKmB3u9DG198vg8wK5R71OHqRv1VpWPD968X/zIVYa5jSCLkVFC2DEr1kuAmWOJ+H5s3smajvI7f2RNZmwg/BD9OKvLjjF8CTaiObV1oX/Nu03jf6qL68HbnQHQw4zcXSAzTQD9n3Fn/4FnEQM2XCXdJgJ7u92RG0MsTYXp7U8jSaK94WUnuLxTDfv59y/lNCUtkgVDAV/eM0UHDs41t4y1xbZRyMW+fvDq4Mx8DDCFCY0MOy+XwTAuACo8X7oRnNqdHkoQlMcQ4SzLjiRGS2xhzsLNyOaeOxFpM4Vx9PaGJCoUh8iLw4rC+WndmyRVaGhaX/Ng52hzTgA+tY7BNvMMh5VFoLI1NipzxGmJBByvODDIGG+cTUAlBCa284Ef1V8I/Z95d/+BFxEDVikqFs0Ezg67ozcHWZry06qPo0g1dhGlx7i8U/X7Mx5czm1IXiQLhnGfPzKEIwdnWxrG2uPbyaRiv/6/hIx8rAnlj+GaK3FojNecvUD4x1u7/V0lSIkxrkSTiJgzPajsr/OFwXRGLUJ5OVf6Nf/haTIZqVc9aLd7mi7NgoCiY1j1ZLX7UFeqAPFCu694hJntiypy1TcUGIudSIYZgRw/1yBkWBgi3JcnTC3gdNljTfcJyZYnnXPWrp8YY3lUpCQHevq6Ymi6TG+TORusr7uTfYjrtnfy/ZM/KeNepOUSo7mCHspKSVIJUIYRW+OTescvTVclXlrPEYaOGe7WaJXT3p5MCHRFhfH2ziWf7FLb0TA3uyPlyJlIjbELzYY67ecKnjozTSoY0Lu2lV/pS8vUT2s5qCcfkRVnbwfOHcP6msQLEwrZWckHFRu3y52hqNpwS6L39QDW4uXAhcvTZqeOdZkJj3XET14g65H1GbWd2iQtdO7BC0BVKO1X1zhwio6sKmSE7VKJ3NEWTG3iVxetPGf3/q1yAKVzsrU4v3gm5eSPdDO7jaHOCioue9hbBBzFzvmrlKpe/4d1hzN2vGibjpmGkHXagw1nDfIfWx5uJ7+SRKgvnJZLnuBftKKYo5owxhJbQFd/+/diIE3yRwOQl6489h2e8V74cqri90WHvrddtrW1AH/ZAnmpbYfgbmR7pKEAZEze/drrsMQs4Nj66/diZ/g3WMcLt+Uh0pvnC2TKkU8F96xZ5sg2kum6PW/xV1uV2sqh7B3/ik9xGrQHVumAvAom58G8iPFJPuBndaYSjc8TUClzwKtNtfwboGLlxrJyTWAB+ZkpID9UE7YoYYJXZ3ds9dR58DzmXTdkbpm77+SN05h83ic3qukEeKPlHUpu8tnbanG9/VOb/zD4c1XRMHb1v26vxsd9t1XIZ1kqGWupAuoXMLe/cUEJolgkVx+AY/se3bAfOaOoLl8m144MHgTh6w8n6JrjW/8mjU7+SJKcpmhNPGkjWx99ftd8pZOEW315JGHnvbaJyTtt3J1H9D94/z95vyVRFUDjpPpyDy6xPCXVJQ9wgws+fX2KlOZN2kD9EQ9WVVrrSmO3v8yWos1WzzbZMHh/6AWoDakJnyvMWbr0jpm53JBF7a6OJOg2N2/FRdvFyHhxKWu9bf9mcbylUbxQCJC7hRVl0teRfdS2nYWGLw8EGt12yknd705MJeJ9YzsplbYRkAZiJMeukp6dI7nGrMnesqJAnVqIkDkrNrvMBcXBBCHjGonZlmW2izxWB6iZAvKQCx2+HecAeVS60FP09f/2xE492F8zU4tHNs9uVk1GUWYylwCBLoXclE7pC1vQ4mwEQBJ0o/v6dGNMEgO1UKsgq2DoZP8xUje7c1abpkE4Z2s0sQuvTT+/+8DtKR2MdH7Hovi4JnMXVS2Yjt1JU2doh17YlVk3u9us9dGecPWQHURKlEaSXvavHYvtoHOttrK5cvnVv5tHjydjU7FLG4eB5x3Bg0NGmaWuk3uNKquPAMzfZfZO/f90ni6zR/dbgETUKaDw3ymRGZB/Ywa2i6WmMOmoqZYUOKy8Hoq2Dhb/WTEYqp/ZG2V4vVec/Zb6FriRHWsKa8DuKpNibBoxUV4n3ZMWTGWiSNaaANoetnl8du1tvvGQ0n0OqcI8MrYbw2xIGdk2q6x4TBHVmJ/OD+mxx5g4FAfATjr7e0kULiiOZSez00PZrStDw0ArRFOIUihWV7YOmIgTXPrTQHeF//N8eV2FJMoao2bSmgcUNF+icusiPI80KV+uuSft6nx85UbHTRCn0f40v/jfE6cFP97miymdECX7Wo0K430ZHdGBx+uEuKPNMSmMOqioPanKEDhpXPmmr6P/N+QSo9yGRfii6q2YZHpIAhQ0q3R6FJ+wgytsvWvmWk6fMrpa+/hQ1/5358913AcwWkT96cKER2Lud9nVlbMTvAEYHdpKgQ6b8PvflZX/uzyfI3unrrla2HdwRw8aRLu351KARebW7i3J1jppzSWgljzdQ07z4WkVW1bo0dStI8MKKkm7wZP3d94OtnArWjL3HPAMdvL0C0Nb0E0TJfycaMkKQ2A4wnTOSzqrcwuRghp5uLpu+7eKg68VJC5gl9Pa4glxsxSxpl4uWnBhxvv7efhlatNOBKbYuIeiQsUR2znJubm5mYX5BbkZBSUFaYW5o9v6VfNtJN/tujyi0BwvmKMyZ+vPjZysKaouL2iO8F6s8JLsvvRAi4bDSXC0LosRN9dRCyuhq5sAWL53xO9YqX77nzmaio/9V/I91qexEg/+jnYTWLHsFdDCapqby2foKwaQ4k4kVW4cvn4n80yFgiC/YVRkGDKWrPhNp9Milg8du3ppZEuYIUgfaDq0GDe6FeqQHeselFIZ6j5XjpbgqnS6lZU4QYUIbPF4BIyt7Mw+GgGsYiM2Tp+4ruyktO3ipjfTfzLqU7ZIIgrNAVYWXo25XtlyhJCTKiUIWnDXq5fyfzwT9HU8ERb9cIIsCjBrLQmZGa0JmDVBJeZECzdrqv8psIJGXPxDV/8o/+e58lpGpQ0r6KMqXCnFYn0MKDjUaA0pfQ2nCOy86jJqGT4zMpWQOs+T9Zzc+OoUv82y9Y4XwO3pu1uIbXHo7Tb4ibiqs3/o663wf16oqKkcjbcNUNLpFQAFh1eRWXUhyFmZCrMbTfcWu8Xvzp4VPwKWmhEm/grLml0SX0VDvywnRox9LZ0whqvdfVbRIDK2xAO4+lon8BrX/aszx8yedPlBVpyjG0vDg20c0LnIBDgP0UmkpIfXPWk/xJmGB0JcBSiDLgQpswDv5+jmW7wvHh4PE5NIGWBXpgVdbaL8Qvxue0aDJ62lvLaX3Iv0/Rj7y7fCV8hlxwGUAIcT7elS1kkKqoITKmapzNnaS+PrNYVVpQXN4T4LFb5gUE8Ot/ClQwfleKBFcd51RNvvS8eCniYO+M3Jrhef0Saq4z5hFV0eqQdoke6cLziq/gI33Rfxv0GWZjxGibkDo07UIg6fLVhcz/9swN0ThVGy1+IY5P4ciJhQ/xMHFu0KtE9ARo1HjxVoN9mdcDjhdOIYAFDcwtdCf7N4fVah4lXHYUPai4JFwxtvYbGx4iZS/F5/lQ4h7bWpd5itb2ixRxfgG6fC2piOFR8KYRoENjiOKgQLWHZDkoO/a0gKglxLAilwV7q/UxKnfgGTKwqQ4Vm40NE2vITiFA1Vvjq3OMER7UzjIQIBMNrSqgNK8nXAD1UbIMM1d6Gh9yYkFierq6Zq8Ip5dhhnOtc8EIgKwTyGXZ9sh3MNSUWQa8mpCFc61iWR0zCPBRYtWONonb37SlBmYs0C5wDvLD0GDGcUqWvjUYzSaPsj3y3QM1sXKG1YxMUV+xnh4fRUesGlhtX0PnigoUMpWr8eHlWchPK28MrbFwvlQsUhpEwajy28hoOSkkl1r7qvpo+b/WrezISX7kH25IR7Wx7P8kxG8OD7qeScxiTnfcFl6AQExZPGxrq4UxsCimCPIyOBRlyGgxccEeRgj0TA7UrtHLxgcJaDPQkOswN+KO2dVdWuIsCt3qjWfa4/l3rRRjjSfHkfXpODGXEQ8l6/IKyfV7wtzo85X+cRUtFWloZ2SU/MJOAmDnQDLZfrTS3FMTRmwjUF0k42j5o72baAr9C9mI8yrjHzTo4PwRNy0Mm5ibm8KDLKl+aDRKZaxqCYD+qcAdoJh6vW3a+sxSIUmZND8pyLlRDbsDJM52AJUHCSbApLReVFDRGeC+W+wEh7LaXaBWpkbeC3bz2Z4MtSOQzcNztYUdHRUdHsKE5kRGRMVM9Ks46J5ID4BtGG6Gmz7R0v3+u21td9ve5YHYeGZMjfKYCE4vqfr3K2+P80FhbP4eaMKAr9RDn3LfOGa8A4BFIfmsZJitfOoaTHhYSkxlIztBlRSUx+L9ge9yxKtigPfRBuwnL1JZjutaVC8bZYqIld4OMY1Sx+baQ1efB0OKiZvfsj4HNT2lkH5I0me79Ot6RLDYWkeCbPMJtoQIfsNoN4mKUbJsyc0OdBUsx3c8wBhmrfntnuNUibiH2ereWlJlrSRS2NZQIs3Zh3qd+QB0vDaz4/tAT5LgWojqcdLjEL4vdix2upHU0dF5HKV9m4Cfn87xYAV/+W/9C64XynnjGLAdJumbxPwItlguEdwM35/NLrbbubcr928Xw2mnq/sOdkn44/XZL9Gt3Q57kWy/ddb23/HDItu4Qe3bYVw5jNK4mSnontllOptLUdkDvNZR0qymfMbEUB9kvp01TPtcbWz7TF45Lji5/odW0eq0nPJx8LWNOnaD0gXhLfD07Rw6fKnwH7766jd4oSXg81Yr/0XCoJEwV25IaiWtfov3rP9ZlbDl+/bTXYgzjfR/vdMg3zy+kIFJWF9lzGfqsfTnp9rxAQszNrQ30ON+y6Vnt7sUf88Ma11psVNRe+6+tofYc/LBhmONJVs42pkYKP2g2qA/hZ7B7YLmxbgdh9TJvAxqtz1D4zgyv2Aot4Y9GVkJzp8ra+mXYdpWXNY6dX6nLWH8b1ZR9AoE2hY0DBebjo8n1OTS2jyZvWVp6BQ/TtTViUDLUnM+uHUGmpDeFD+7sqygbKAXIJp4tGGFOtj+9Z9F/y1JuxPWZI1r/hfvBriJ9VoWkaRykKkoko2P6UDcyl2qJTfmRz/4ogq4l93OgIhreTMymfynHJ95tuC5fmDxU9epbZ3foksfRCS0XK5np1MZRonRHlnU2ov9y8LA3VWmLnTtWyg5paguOT2qlBg5mNjfPgYqmoNbHeCsPwQxOoQhg9bdoRZdz2eNa86PXDJVFBYx5HX4Wln1IQzU4sO+qXlzUGJ0G9BH5GjQh2aSmVxJoktQJ3EMYk9NgjR1X2RZqGQyEOiRZJ6hXac4lMadX+yJ8Tzx7fLc2cC5MtlvWTr/1WfHX+1x7BU5vjjCxyca8XX5urUertzkzyIv30zDVIR6a6qyvydkUuVCb6f1FFtyn94HDuHp3/79NQ/g9OzO0jB///4xGjP3eN9Ngp2InkbMSOKnHQwQ4DZb0qZb0uA6C5iVPkEuPoVqwd+8uPJexyDKtxD2qt3A5UDdvd3AZNwojRIVAuulqz44VOXCGG1mKert32/eZllz074a1FNy3j9thhjB38A4bOLBpQ9Kla+HDF3X5uXcZ4xSiAm36bs92yAJ4tVCopaTP2IZ0buUvMOkEZkywAvoRH6hFwg7S3o9U5/s784BhqSV0QRXuYKBchuxdVe7LcjTkJryFS8igpvemHJWVTJTOUsCZWQkjKgHOKNk+rEOnCcGfge62R/aoubONwmDEk2TJFo1J7IS5sFPh/yTJ48ErwN2rn3uS0stKrD46PHH+MF/tg6+5uBoQDzDPYSubP2+UdjD67aWX0tvpQq3GTlaw/7uSLG66XZ/94+K2v48ol2kKvY8hI+92bt5pvAMSfEeRuSLVjLafICH1o+OW9AvembnKDEU+rCOnC8GASBo71b3dhm4TDIfZJlkkaIbva0MnZHnPFFyoV3pcCzNV/OzI+PhFJ9j8uzv86c77xh0r24c91SsHE6MeOXwQ5qOUWbtbBvlsTYYghQkMy6tblM2CfHK5hOiU/iRNuw1b9p/h8koZHZM++iFZhKSJI7AP4GvNnhJQ37aES6nLb+cGx4U//NUCeG+WPaZIM9u8YifWUsQGaTtRSJoHDetTSEXlohBmrxD88dqK9aK6K/W14Qyzzr0CsdHf4brfSx7yqvzfHstVvq/uFJpSnpyhN8TibLRX7FuNYYLscCUl28eAZEMQF3pHz47/7rmkv5R87vRvq5fRuCwbfJyDPmNbVwh1YMHiOndsyCPYLcdSA3azErgDnDnUgv79AeT4+ar2tweSjce2ocZXxF9HlVtkfxYNK94fv98l/zhL+dRoyAu2OWZZQ4xSAfBegOeEsWM4LuitJQ/R/JuvKMuojIWHKRmGNkWlF0yLmX5IkvRXneQv2hE+Tp9yB84WXEjFMjGVBsPuAO8Mmj+njE8CNcJVWHfCUQzYBrVHpJFqVD/Q1JlRUJzGqV5RVJ9GqwFxL6vJd2ujyUgrMl8/kD9OiOixOZRRaKUX83bx1Jquiui/FbyGBaDaDH8uvniKls5pDrQO0dqkDgddCQSjLq97Kb2BXmF78LrMQtiiG2Ws5G5QS0cilVkXHDaE2d8Ro0fNzwNYnoDgaxmzSVFNcIAj4lIBo64dXOiV6d5ChqG2wxZyJjgT8/4cCX9R2Z+5YFhp+nIXQN2ugf40ByrUrIQHNAnpoeFcCMtMroZPPZFYF4xvYzMCGKmpoSBfPJ8Od25MWKRg+2CdyjE0J86dGplKCw/lMND+CGkmNTqagUsJdOA7RfBaWEpUCWt7DArZ3irjIHaZRlHI+kDcoDxpsCYw1QStx65jHIT4ED5NkPJDXX52bAnbOsgVuqa91q0Mqdt+t1qnUz3dJfqFTHVKy+2a1Jti7/mj9acDa07VHZlu+e3x1fHSAFc2k7GLjxdaYdlSdU9mOy9ayKZBxT1b0HABw+Fpikfqb9tPQmsWGssap3hFUnf7dsrQamGsknx5GTmbGueB3vl6GjAEVR1rUv+cymWxts51AO+RK+mByKoHOQRpTTKL4tPQxUXW0yB2bgt9nQQ/wueWLQIcSk0eyqC/+RDpAkBaedEJIKA3v5RlGougBIZrg5eZG8/8HuScI6+5G9AJQrEnqVHBxJ+n+7rqmOoHWHqMh391VZy/zGxIa9tFjoWXYfTtS1WLM7OgmupB/zLIh7D1O0SQuaa9a4o4sb1acML1IIqJpXNLR0fpf1jGtbjWfHiDqDs4UsUIjKCRu8WvcCRnVZM8JZla6B+Bu4ur+NSU6jOqP03tDbkwml6U3RkLCFE3CGiP5R7Y+fKVDJveNQgmagS1IVFmdBgTrNmw6Sd8o6EqO5XTmnhk6w7DLC/XxScrtXaXrje8dAtpm6L6eN4/vi98d6Ot//eie+ONobgR9ZGqSPhIRRhuZnqCOAMNXV40xitkZXKwKnF9G39cqH650Ps2Dni9urGQHimoCWKxWGv1gJRd+JKp5gqq94MG0skMjnC2j6V7epJioKBIjHGiF3Ixoo4RMVnHhx9htY7QKM3/FuCym73b7tOIwN7EcQ+VQApJa0dEiFErGalMIHFYEmRrFdGda2qMRXhaRNFegirmIodl4RBsG3dcufCg1yhSbLJtRHJgk2G55ccm9AFU4ORKFa9mbdVfTaBvrELRd40esKcMl3EVD8V3puWdA1Vk6pfvrkJSBEhTTGTuV4nc2UHH1vMbKI+/D+/d+mFQZtdZcGiouKlnOPvQzx8Z8cbatiUnOHvEoBXQJTjI3vwSV8X6MZyxcis1Z3bdn8T07+NrSrORG8SEcm/dOTLTYOpW+REAmlZw2+iFr7eqAvBQEF/vlJg77Uw9Rje+zCquChMUj63y/M7x3BNFtkjmRXl4llPgHCSLAVvq1XJczjaa45p+Rc+BP6ma9Vdvj6Zv3O+5TB988CgCZ28KhSgwfTsVsMjC9XtKxhVz27cQyjVUf8z3tkHc6A80OYfPaMrSOdtt4xlqxcnOQffqDqjwt1Zi0xHFQXZa0AA5grUQj9r1VYmn03P5ABacdSIMGIHLXXicVlW0Ep3xwg5cujrAU8+xnaBPEN/gGZAcH4FNrGZHvwfgY/bKJgZiset+0WwFGOXh0Ij6xjV+ULU5LJATwigIZHHvv7B95Eb5Y2bLpQm4MsjXkDzJuqjPjflvS835gVI1MzzU3jraCeDGJVLSYVFAAUFABDMzBC6zAGmzBDuzBARzBFTzBA1IgASg8qxsBoovgjKxisenv88CBMZAHhk2YP9P7mDC5VAAABwfIzgPQn9A3mBBMgnJ2BPkYFowqUG3FBtaSUwSpv9jF4rT/txbzfxO6Y3/OMoXewwD8mNYTda7O0xf0RX1FX9KX4QiK6vj1lwSdq/P0BX1RX9GX9GU48uoUgDp49ozclLBsHRbUH/im31/mdxlljz7v73UGsHtXmpnud0W0bTPzvgKdsnOnfV4IW9v45MMX3w97bC/yjUodfDkHfC+uwM/ks909BLfyv2ZQfsYrh0pUIsD4fpXcaoyF6ONo93cs5eFhjeAfOMZd1t6W6gpPsztRpC+B+f/y1SeG9H8ud4t8IB+dPPj/2z+8/avExn32/6X8LtILrrG4X7p/ShAA+WhSOEB3mVKw+7UbstKym982mbzvp64rCdaeoSnmburJyslTbp8iZnOt9045i3bn/j2D0IH1dA9x6MDO3LNg7cENWWnZTZf3OO9247oSsvYM7WnuZrcqJ0+5fbeYzcW9e172G7210pe/nz3v99v55bLk1v35u/T9Bez898vp9vzYj9cvn0fm+VbangZ63/q2/jdY0EfPn1jn/64H5twECChwyC/xC1ObC0y4GzLkh/oqF60paPllq1WcPnY4Yq0wIm1KT5/4vYFfa6o7AkXL3uEJna/mtjqWd9v4sHo4vT/Tsomv8Dgewa25gGdxlsZF1qV6mMozW+FOFuOHNXbfneD748lVYb+95EwyoEwsv8pehe2JCfg/QjojNoMPB5hH4Zp92C9XNuzL5yQcCeFR35tWcgpIrWOUAQq2F2CnInY/ibo2lCNmR5ry+6PdsCwZ2Hlpdm7KgKWsJOz512ZiMs4bsy3PhSgmzXGqLRgPnqDlcoVVzVLz9MGYnSu4fQ9k/uM/ML+BMBxtsUPvyKLuQaQBjE1cfRjAdDweTxNYBXvnQLlgFJ3hwGVYvtFsVgQKhDQht2IwKJWsxtS6eIWxwNAwGIjh2V8VYiFyzJZdB4rhQYGx18NcwSIRnMCmGFZLwKnFsAb/+GBxnstYOW7IHmTsOWlzTejchRhy7RHpfci4OsXg7p9qbhEa4J6RhscjrDPac9nIPMCyYs7SzFOEe8w2D79fjjKXHHvsUrfh79NjlcL/d2VY3Nawfe30KjNvuCqWDzsse3YjU58dekJyn6HFvbn75k75SDXcSxsZCzii2cYwirTzEb/Fmv5frR4e0aPQqRiiUKkp8P8Z8G8Kkv4u888/QNBHUtaAhTwhflaZlDk5HJMoOCKMdLPLzUvSLDPqKGZJQXenxIsS9nkIAnz1bpFnGjn/JdccKnD9LrRMtfTaMjpQiEtVaVn//0DHKE8eaHRz+YGeDsceGGjY9oACI4xZTyBiABwoZOnWYKJD6SC9RVVIz6pqnD1YsY/yIURNAvEArD1DUWFZNamUPq/sptcALEpeWrE38OBUxf4oAlYlXepErLwsBCirdOiOsqbOGgMxkFUdO9ZnQKU+hUiNDUV8ipYeT3XpxJkzl+UqNTsBNckWPap4VSfdsUdp9Y0bkhAV0PHYq2jIkeqCxMtINRxx4wYVU11/RDlzhFdxToqY/WVg26o99DJxEVugNUppRFgnglKmKAuxwcREoKtOWcrLxFclRBaUZ+eY9HLweF8BouJw2DdKyGSKvxbmKdCFJkWxkrJmLVq1adehU0VVTV1DV91010NPvfTWR1/99DfAUwAgBCMohhtNZovVZnc4XW4PAEIwgmI4jc5gstgcLo8vEIrEEqlMrlCq1BqtLkpVGo1oi2CYVl/cGaU7Hrgb1XZcz+en0ugMJovN4fL4AqFILJHK5AqlSq3R6vQGAITgvhAUw40ms8Vqs/frzNGry2ejWvUa06Sd2EpOl9sDgBCMoL3WwnAavT8Gk8XmcHl8gVAklkhlcoVSpdZodXqD0WS2WG12h9Pl9miHQGiPmk2u0JdTAmduuE3XDHrUc9yN++2DnH+OUA6LP0AtEH4w3FpiBfk+Ymgee+KlIAaPEmE+HfKlpXBoN5FQo6Gh8Q+GGpSa3qfRdMS1Uq6dclOQO1+nakGE6wLft6k4AMtH/BCl8qibKr5rA19Qv9uXpyiNTpFsTdMsEr+5VkE2rrQ3bkCiAbjgSRGPMBdHUu4FZHr6QT5iSS2tQGMVeKKnPOCYBeuK1DcsJH1tqrT07ZkEV+kiuLJZ6mrSs17TTXhh8+Cy6s5tVnVsbkxRcxsoAi+/PHc744oS70iItUk5syQdRVqzjyIT8HQDU1+7l6mQbfJXYhNfaeQyhRJjm0+ec8p+syksgszXoXJ2BXhiWRLDC37VLXmL30JL3i4hQEgWH72PFMValBZIKe0TyaXYWEdss48CsBRbLMVeLC1IdcXXP0HArQ0ECbhCwBsEBAF44wCuEBAQ8EZqL+szAAA=) format("woff2"); - unicode-range: U+0302-0303, U+0305, U+0307-0308, U+0330, U+0391-03A1, U+03A3-03A9, U+03B1-03C9, - U+03D1, U+03D5-03D6, U+03F0-03F1, U+03F4-03F5, U+2034-2037, U+2057, U+20D0-20DC, U+20E1, - U+20E5-20EF, U+2102, U+210A-210E, U+2110-2112, U+2115, U+2119-211D, U+2124, U+2128, U+212C-212D, - U+212F-2131, U+2133-2138, U+213C-2140, U+2145-2149, U+2190, U+2192, U+2194-21AE, U+21B0-21E5, - U+21F1-21F2, U+21F4-2211, U+2213-2214, U+2216-22FF, U+2308-230B, U+2310, U+2319, U+231C-2321, - U+2336-237A, U+237C, U+2395, U+239B-23B6, U+23D0, U+23DC-23E1, U+2474-2475, U+25AF, U+25B3, - U+25B7, U+25BD, U+25C1, U+25CA, U+25CC, U+25FB, U+266D-266F, U+27C0-27FF, U+2900-2AFF, - U+2B0E-2B11, U+2B30-2B4C, U+2BFE, U+FF5B, U+FF5D, U+1D400-1D7FF, U+1EE00-1EEFF; + unicode-range: + U+0302-0303, U+0305, U+0307-0308, U+0330, U+0391-03A1, U+03A3-03A9, U+03B1-03C9, U+03D1, + U+03D5-03D6, U+03F0-03F1, U+03F4-03F5, U+2034-2037, U+2057, U+20D0-20DC, U+20E1, U+20E5-20EF, + U+2102, U+210A-210E, U+2110-2112, U+2115, U+2119-211D, U+2124, U+2128, U+212C-212D, U+212F-2131, + U+2133-2138, U+213C-2140, U+2145-2149, U+2190, U+2192, U+2194-21AE, U+21B0-21E5, U+21F1-21F2, + U+21F4-2211, U+2213-2214, U+2216-22FF, U+2308-230B, U+2310, U+2319, U+231C-2321, U+2336-237A, + U+237C, U+2395, U+239B-23B6, U+23D0, U+23DC-23E1, U+2474-2475, U+25AF, U+25B3, U+25B7, U+25BD, + U+25C1, U+25CA, U+25CC, U+25FB, U+266D-266F, U+27C0-27FF, U+2900-2AFF, U+2B0E-2B11, U+2B30-2B4C, + U+2BFE, U+FF5B, U+FF5D, U+1D400-1D7FF, U+1EE00-1EEFF; } /* symbols */ @font-face { @@ -80,13 +81,14 @@ font-display: swap; src: url(data:font/woff2;base64,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) format("woff2"); - unicode-range: U+0001-000C, U+000E-001F, U+007F-009F, U+20DD-20E0, U+20E2-20E4, U+2150-218F, - U+2190, U+2192, U+2194-2199, U+21AF, U+21E6-21F0, U+21F3, U+2218-2219, U+2299, U+22C4-22C6, - U+2300-243F, U+2440-244A, U+2460-24FF, U+25A0-27BF, U+2800-28FF, U+2921-2922, U+2981, U+29BF, - U+29EB, U+2B00-2BFF, U+4DC0-4DFF, U+FFF9-FFFB, U+10140-1018E, U+10190-1019C, U+101A0, - U+101D0-101FD, U+102E0-102FB, U+10E60-10E7E, U+1D2C0-1D2D3, U+1D2E0-1D37F, U+1F000-1F0FF, - U+1F100-1F1AD, U+1F1E6-1F1FF, U+1F30D-1F30F, U+1F315, U+1F31C, U+1F31E, U+1F320-1F32C, U+1F336, - U+1F378, U+1F37D, U+1F382, U+1F393-1F39F, U+1F3A7-1F3A8, U+1F3AC-1F3AF, U+1F3C2, U+1F3C4-1F3C6, + unicode-range: + U+0001-000C, U+000E-001F, U+007F-009F, U+20DD-20E0, U+20E2-20E4, U+2150-218F, U+2190, U+2192, + U+2194-2199, U+21AF, U+21E6-21F0, U+21F3, U+2218-2219, U+2299, U+22C4-22C6, U+2300-243F, + U+2440-244A, U+2460-24FF, U+25A0-27BF, U+2800-28FF, U+2921-2922, U+2981, U+29BF, U+29EB, + U+2B00-2BFF, U+4DC0-4DFF, U+FFF9-FFFB, U+10140-1018E, U+10190-1019C, U+101A0, U+101D0-101FD, + U+102E0-102FB, U+10E60-10E7E, U+1D2C0-1D2D3, U+1D2E0-1D37F, U+1F000-1F0FF, U+1F100-1F1AD, + U+1F1E6-1F1FF, U+1F30D-1F30F, U+1F315, U+1F31C, U+1F31E, U+1F320-1F32C, U+1F336, U+1F378, + U+1F37D, U+1F382, U+1F393-1F39F, U+1F3A7-1F3A8, U+1F3AC-1F3AF, U+1F3C2, U+1F3C4-1F3C6, U+1F3CA-1F3CE, U+1F3D4-1F3E0, U+1F3ED, U+1F3F1-1F3F3, U+1F3F5-1F3F7, U+1F408, U+1F415, U+1F41F, U+1F426, U+1F43F, U+1F441-1F442, U+1F444, U+1F446-1F449, U+1F44C-1F44E, U+1F453, U+1F46A, U+1F47D, U+1F4A3, U+1F4B0, U+1F4B3, U+1F4B9, U+1F4BB, U+1F4BF, U+1F4C8-1F4CB, U+1F4D6, U+1F4DA, @@ -108,8 +110,9 @@ font-display: swap; src: url(data:font/woff2;base64,d09GMgABAAAAABQIAA8AAAAAK/QAABOpAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGmobi2wcgiYGYD9TVEFUXgCBOBEQCqw4p00LgiYAATYCJAOESAQgBYR4B4pUG1wnRQdq2DgABtfGIfv/cMANGAI11H4HdagP6go7obWvdlXpMZrlxGKrG02Yxg8fEUouGb7tYEcxEEb8oTrC4NpAm5e0IqD5z4NL5N/Z+L42rzb+P+FLhKe8l/88zdmf+2QmzCTBZGmYtkFqDjWl4lhFLDVKKlkxqJDdb0JNPVLxrIjAzNFam31MIpWNiPu5/akiFho1Q0QtW9/+fHARhUKhUFA+J2Fz1ChFeYRFYu3yDJmweWgSFTYLZErK6y8b8y6l+QZ+R9NLcR+Cm90z/DtMquY21+TgSW1uTW5iY9OjQWz7/7andHQzLlrr16KIQ7zfmEjqIWzOgSEkwVC0PP3l9r2u8kI9PfUNaOdqtXNIBgry2TOGCnInieb/oa8vLbCsI5ZpjnF2DRhdZKQUiSp37MhBiGHkMHRo9muv5rxdSZd0N5lkOEbGCCPEYbwqqe3rJn+IIExTAAA4EQZIB9gRxfsqrLTKamsQUomJkigFSZOO1JaF5BgIGYyCDPULed/7uAqVOD8/QgBNrgJDaxtPLODT9yoBfFm5MeAr164A31lNBpgAwLIUAGFXMx9m7uNmK5gGMGT99gDcJmVGKWIQDSElREhHdoqGshjSJHCiibmrCLUnQ7VchlD9Mjcb1dR2452KHwrIeaY5mqUZmh5ySohqMoJOF0EnyVUvUF1ndvEciD/oKA9tc/hQX8Pci6qXcthNTJ90T0e5mmsoiyFNAqewCcarkfJf+Hf8C/6E3+M3+CV+hh/jUi7hs3ycD/Ju3spbhDOvFERergrfouVUSh6aqSb7Epf8qKACGkD51NVo3yH6+GSE7cOb86a8PndzF0/hcdzOFRhIsz9OyH6ib+gzekVPaqGQNLvzMOyaQLIL7CC/xxbZdHfFDtbPOt3qX1zYRKupgt6gHLXIlxLXn84mstGsBDSE+lFP6vxG27KWrDHL4ZeYOj/GFFmSsLEYXs00Jsik31SGfqCv6BN68fQe0RU6RydojVZonj+hSf6Btinqpf+9kr3UACLNXAsiJvJBjORTEOug9tW24jcj0tHSwVybkYf0ZvibbVme3MSTvWBBErRZwIx0Ax1TrRuw0Rq9IAF/pUvi6U8ReFoZmzM4gz2cwR7OYA97OIMzoumKoVtc6uqsGpO1jbeVX7m3ucJW75I/NoCOGZHpTaOblLaFyVcya79HbJvNM3vYbB71EJp7myskdA9xeV48DnCQP54E2MyILJt6FCFgs3lRnqohftsWoFkxfWzlHCNMQ+bCefw25/HbnEdvC7DffCzT6LyUXMlvO8WAXsD6R9ZfQU+EP82W5a4sdy3CYROxdszaXUAr5yEoiSGLDz6FkCBLWjcxG1d6YbSwkwDnMwg+K1uSk7dPqVLkmxTqUT82M1iwylO8rXc+HjsTjLxzXQHaA1oDmgLqA9yIC9UqADQx5UOotWs5f8mptDXuYR/tGZWP86NWusAddxxBf9TW1OUj8g7k1XMWa7ytnf3zu2ifeGLn4Jx3Tojnyr+phqROEQRQIS9kmwPy9DQtYIN4rnBjDQxgNiM4TUaSxMbGmlTSzwnFN3bTmoi0N6YlaIhC9rGeOdUJ4gJ3/3n0uQw1mE1UCQlywU3Av1SN7S/avHyAzUUN6J/jq0evQ+IWnQHjB7qqZhCw/bMKgL4BQGy1D/VfXSDEBp3QPpuG2OdZEyACFl8GDQLoH0N/RJQekyWJgmNYU6t8RWazoMoM+3UI4rQmOpmVImtSjrBBuxO/XwJgUg4YxCmW6tE0WkuTfB0XPIrXdX3v+tH1u7HdshCPh2AUQzk0lapoggO+UTbMqHL94PrpNwHr6/+IFW+p5vfmfrPYTK+pqBECNXEv33vY5GXZ/SAIcDuBeA3eXyf1NmhwQL1b7QEgCJ0ht5H7ZPx/gFwAyBsAHwmuzq5sy2/ltmrpZtZGKomKl9BV/L6SxeeDUns0Akr6IW26XcRFJ0QJh0tPsQm7fpopLrvdEe00HPEiNq1W9GvRRt2keI2nJcWnOvW3J8mZKuzxw50lmldfMn34v0KhtP8EAiklsd8bGyeLhlNE66ffYa/vQSCgCUOhR1T4OKJXvXxY6nsY1KvCj6n4kSYMPPAqvkBAq/6EILria96jMEEWz9BLhSbL9CUxYr07g8EO0I6FQqH65K0IQmhF2pkBN6DCyIRiej2k7yVQUBQOTysIBDCA6LUyCDiD9/qK4Rk9Dhd6dUSHNs/Ga9OiRlTche+OJrxHhfe9vkAPUUfhsB7YXeqramHTD8U+t9c25pxNusjzsTZ59VF7g8Fa+vpw8Ri9dICFWbTxomN5i2Lv67efBTcTNE7QkRdb+s3P1Wg3vyNNvBUvH8L34IW2VWqky3GacMDO9FWf8sJQaFb5I178+ME8UiP9XyFaZycH6dChVcaeRUUVYSpeFF2WadNboSF3Av00Oj1wAid5A68XFulr72ac3K/rXR++QvHEM7TuEAWe7x1jrqJg4WVM3ZIauFKwy2kLfP1OouJPG1yX9a5uXA/CZ0R9BmKyA6/1jJTbW3zjY/yObF9VK3CJ4YrVzV9w0+bLelWwrExfv/b6ovPhFjrO1O1lJ6py1IqOt6Ir6XuDXVB2mx5qSkUQvkD3Aq3o8nUqvEbXeiCB/n64V1D1AIvnZ58xNBGNq3PO1y2TuLTk4mLsmN8DnA+3OOmPH12s5vNpTBQMTz6r9J3dZ2rEyIlDi9LnLmStL+q3f9T+23323d6h4YscXdmnUbrSEjl8hi3PVvAW7kWzUM4ZY2fAtxXIQ/iWkpvBTcFKJeCEoYb3/48B/7W7Q57IwWM/+X3Df/j9xzmooQeNbL3lxze1lvaySNKnEt6OW41Dwzcao3ZIFN7Y/h6+LYrZCp6++WlxzsffwoM75LHfxkdmJEdOHikb5nLGU2aB9YOSOwvKKfmEYQPl4nIJIA42qRRUgl3vqOW6JjJiNskmWXsw3X2cWHpI4P6L35EDE6svs1S6oLfDWEVaweH7XXxq4no3TMAgJyBOtVlJCV5iIxc141wy9pCZm03/5jOQzWmxQUm+QQ1LXd0AWxBQfVzAu9cc9XW9dOnkUHQH1hPTwMF0qyW0vyoo/Dk3lb7+RlV9eWnb2HaxMxhn2ZTBAYkFJFI/yWOfdi+R0KetW0oglgDX9bhyl8vFIgktPX6eViIiXS6fzfrzKLa1PCjN+WNqzJS4rIp4KckNPJfVkmKXg6Ko1JH2h8CphESqkNkHk+XTy3C0ogl3nwnhucG1SkFZfna9v910kQOAO3/6o8BNI1IhUAC5aNKt5PEke0bpyktseHhzHSvSwA3eUurxXN3WD+/gm2u1DyAmJRvb4DTpxkb2mjjDfMNnzVhc4J8uFg5rCFyL1JDWzix3Hw+mdYLsV2qMW2IuyEmcv+fYPW77+vsMxbP/S16luFm8V1T/ErKgOfX74VtfW/No8f/qHNAy/sIn+USV7wo3vQv1g+j/7S+b+Zji5dxlSb9EnCu+WyEjhj4IZBbhrSsn644cUb1UeXthX8vTM6eabwGVItVq38QwfiQ6nZMU4eUVH+6ejPbm8n0SWoHOX0PKvMuAnny+eRAts9yJ29giggiiveW8kbYEb3R2OJDuO/5qgQQHmroB3h1Dxbti1Awp90O3piYIg/XYGCqehNEwsrwH/LvvDnkgB4/94PeNLEVmfwK6y08G/iR5RORbMFBplOkryJyUozl4vDf+BqkzXxK941bj8Mj1xogdEvmXdn9Gbot422byk5/N/vcotzU8LMv7N7t9e/bruFmyvVO3FQuRRpq8smOUjSg8gqqoZo/pMlUNrnaWNoSmpIrCnKVVQucDopC00bYbK/yVnbCHO1PlBe4TV7bk6xUwIgUuvjtSxakfPwulKPVV/6rmFk+cPFE2wKWPJc8DH+Snq20vvWI6L9PFG+a1Jg7Po5fiqCVTLWcGpV/t+aazh+0Gsn870GUELJASvEUP9CDthMZHbx2lbfUyNDKiaVgphiPCzdI1swr9QFzgZpB6rKeqfYynerAslu5J9X8z+obiT/fEMlYLib7/N89D0dEULsi9cBONstRo59LjfwzahmiuMc/T3pDveXzMNWFk9BKq73+enIwCxtvfQoeWHfSlpIERYc5ulhQr/00sJrRg8T0Ww8ejw9aYlxsvGTvp8x9qzePZ2ADHGPcN493VA9AohgcN36FmxWB8KMPcHOui5IB7q6QtPeIDDwoWsHBuSo6adxW1p2YA4u2H8CVNNdV1dUJITiTEI9TUhxlDhLFUH6COOlBcHawC0SFW/vd9jtpYU1NXK4Q+JItHgLG3PXhP9E9C++u6OfS9cEdReBlvMP5cJzdLsiUlgAkNHLyP0eDryaSu0p709J92D17aWNVcARU47qHGhunKYt0gPDdzw5U0s5NXshlsE/d2dAPPflI/CAnSaSYQm3R0m4iEZrA5Cwg0UEFoI80xLPumOBxQFExwspKnln9YDocAsGzdhLNbMTZ2clS+wx/GQn9gEb/eA/bG/TjIiJ84Ao0dcIPHbiBye/dae3dw2x3sbYjxJLXXI8jOcT2oQPhUIJXN4b9yLqxzJ6/dididvXJn+wYXu7vodFdPGmtIkD1rO8soLRNwOMCCUBp8FA4+Fkpx9en4oYMaj9gPoth0EmoKQq9Vyh4cCChzMIIyN0rtbm/MHay4gx5XtFTkoA/lWcBRvg8HtvAxVvKGV4blFCaT9LJfXugkjrRUewWDo+VitcfIeGE0Gi/b3bBsNzjS2rf27rDM1sGdvbdkxqi3xJqUoUkW2LRiqGhx9DVw3TielbgDt3Fu2mB363RujE52USqXF7irqBnNjiFjDPxPyMfZcPPx0MZMQgwWS6l4YOuYMDN/zkIW70Ymr0EWpyCThyGLHyCTDWTxFmQyG1m8YEXZQmzFLpLh1iuSsMVmxPLEIIptzBNUU+C3ajjF0fBds4JsQ8T6n5dVPr6mcd7481LeZb7ZE1dTOJd/n0oeAwBq6VhrM95n2OMtlg61CKOtr/hp+RxtATlYHrJ2AthfVJr1PoDNlU9x1PpKyqv9sJ46BdF8vQDEErUSzIwXTKkNmF1ymzyB0eZaflr4xbQivYoI5t0pwlZZoRu5yui29cYcOeVXBONDe9SdsW11jecL1TABZ2bNtEpy6maMDOGxuEiUrK6oqd/kIXjmC4QYyWlIqxGPPOQUv9UvK59OENPVu4mPsgIjXR6oNyEE8h1svWdjlF9Dm2zje9SYVE3qmrGKgdUZqp62GKCPa0eojgrlPKrUVJ58hWWL5Io86zvAFSPNtPVVOTfilsAXxyQpK2jscG45F+JKlEFcGbsM4hYxXglVKy+LlFVqm4jAb/Xrkk9jeehSEuBhgfgOR9VUeXkI65cIoshfS1akS/FTp5KJIjplHfYAiEBk9euSd2N76FIS4GGs+AQsFlny0NrsFflrFZHQT1a/h5RP4TFvuqAga6Q4YqbgLqrlxMOaXYpajU+lrcSfSHWKeGJa8qkZdJv05Djz4+2kNHkPG8wuihP50daP8v9j89muqPJNPAJwF3vCTn1m7Gj/QXUbAODhjbXvAC+9t4d+t5qIXGlvPICCAQCCH6J2KosO48oBIHSYD3LTWfSwqX1a9g8lXvyzo3dc2W9ZO+holgD+Zf25uQ2Jh57lqiJRlTs8+cz6MLCsp9auJe1b2ob7ui7Spp7S/h+70no/jvDtaPXwqSt/4qQVtzfKRWwRfhedTi1LhKfTmNPt/kuhZlOcPVFYPl50UaYoZU+J1DNx7xJlpVvdicVER/wquYQke0JnbqxLlr2XVJGvgrJMe4eKvLuEmJvNQHUi+LMVDlTzGtP2ftQcLGASuzXJqQI2ZDvNq6yemsrS/kNtQIAPNMIUGlxjmtNjOu3CUaIA7Ghc6YNIXGNXzA3zIK61KwcJdWw6SEqz8iCFYeZMp5Zy1yLAriEOImjqNIjYnZRGSFLpBE3Val4tMEQuZcnca1gSIceLXCU1ldBRfbsKeJor5Otm7zXTCgea1M/nqISmarSzYn6cWImgfNdhB7rxhEhcGSZVfW3ZEC5U66csUryhq7Any2WwFhprqqkWTTvGLPCOfvXt9EIgWjrci2Q7G7tLsP2lXOFdVXKENYfYR4aCDrm7zSwapApLIi4nIO6iFUyIIVztOeKF9V08ReiMWjbpCXMiLFEubz2KXZ4kQtw5q+akC+tm0Txmc6LWf2rub/oHQIU4OLccDTWXq72uLl2584QmUv1Z5bGXhKqhG6aVG7mV27lJtx3X8/UGo8lssdrsDqcLghEUwwmSohmWQ6ijq6dvYAgggmI4QVK0kbGJqZm5hXMXLl25duPWnXsPHj159oJAotAYLA5PIJLIFCqNzmCy2Bx9Lo8vEIrEEqlMrlCq1BH21eq8evPuI196uUxdVu583rv/Lmcd7/Jq34/VN3f/T9etEYSwOKsdLD1eymH8vlmWOI/3PZtXzJltLVPdz+OSb+8JgwEFBAEFA4eAhIKGgYWDR7BizgIQBBQMHAISChoGFg4ewYo5B0AQUDBwCEgoaBhYOHgEK+Y8AEFAwcAhIKGgYWDh4BGsmAsABAEFA4eAhIKGgYWDR7BiLgIQDBwCEsrUVydgbPsxaFT+1x9jdZPf3eZxW3fFO4FEQUss/V31Ee85Err2blaKUr1fHUBXIUOrZ+RlEsIm/85OoL14QXsxUnvRT2S+BCgwlajK9n3/GE+OWF4+xa74+z4AAA==) format("woff2"); - unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, - U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; + unicode-range: + U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, + U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; } /* latin-ext */ @font-face { @@ -120,8 +123,9 @@ font-display: swap; src: url(data:font/woff2;base64,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) format("woff2"); - unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, - U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; + unicode-range: + U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, + U+2113, U+2C60-2C7F, U+A720-A7FF; } /* latin */ @font-face { @@ -132,9 +136,9 @@ font-display: swap; src: url(data:font/woff2;base64,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) format("woff2"); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, - U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, - U+FFFD; + unicode-range: + U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, + U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; } /* cyrillic-ext */ @@ -201,14 +205,15 @@ font-display: swap; src: url(data:font/woff2;base64,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) format("woff2"); - unicode-range: U+0302-0303, U+0305, U+0307-0308, U+0330, U+0391-03A1, U+03A3-03A9, U+03B1-03C9, - U+03D1, U+03D5-03D6, U+03F0-03F1, U+03F4-03F5, U+2034-2037, U+2057, U+20D0-20DC, U+20E1, - U+20E5-20EF, U+2102, U+210A-210E, U+2110-2112, U+2115, U+2119-211D, U+2124, U+2128, U+212C-212D, - U+212F-2131, U+2133-2138, U+213C-2140, U+2145-2149, U+2190, U+2192, U+2194-21AE, U+21B0-21E5, - U+21F1-21F2, U+21F4-2211, U+2213-2214, U+2216-22FF, U+2308-230B, U+2310, U+2319, U+231C-2321, - U+2336-237A, U+237C, U+2395, U+239B-23B6, U+23D0, U+23DC-23E1, U+2474-2475, U+25AF, U+25B3, - U+25B7, U+25BD, U+25C1, U+25CA, U+25CC, U+25FB, U+266D-266F, U+27C0-27FF, U+2900-2AFF, - U+2B0E-2B11, U+2B30-2B4C, U+2BFE, U+FF5B, U+FF5D, U+1D400-1D7FF, U+1EE00-1EEFF; + unicode-range: + U+0302-0303, U+0305, U+0307-0308, U+0330, U+0391-03A1, U+03A3-03A9, U+03B1-03C9, U+03D1, + U+03D5-03D6, U+03F0-03F1, U+03F4-03F5, U+2034-2037, U+2057, U+20D0-20DC, U+20E1, U+20E5-20EF, + U+2102, U+210A-210E, U+2110-2112, U+2115, U+2119-211D, U+2124, U+2128, U+212C-212D, U+212F-2131, + U+2133-2138, U+213C-2140, U+2145-2149, U+2190, U+2192, U+2194-21AE, U+21B0-21E5, U+21F1-21F2, + U+21F4-2211, U+2213-2214, U+2216-22FF, U+2308-230B, U+2310, U+2319, U+231C-2321, U+2336-237A, + U+237C, U+2395, U+239B-23B6, U+23D0, U+23DC-23E1, U+2474-2475, U+25AF, U+25B3, U+25B7, U+25BD, + U+25C1, U+25CA, U+25CC, U+25FB, U+266D-266F, U+27C0-27FF, U+2900-2AFF, U+2B0E-2B11, U+2B30-2B4C, + U+2BFE, U+FF5B, U+FF5D, U+1D400-1D7FF, U+1EE00-1EEFF; } /* symbols */ @font-face { @@ -219,13 +224,14 @@ font-display: swap; src: url(data:font/woff2;base64,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) format("woff2"); - unicode-range: U+0001-000C, U+000E-001F, U+007F-009F, U+20DD-20E0, U+20E2-20E4, U+2150-218F, - U+2190, U+2192, U+2194-2199, U+21AF, U+21E6-21F0, U+21F3, U+2218-2219, U+2299, U+22C4-22C6, - U+2300-243F, U+2440-244A, U+2460-24FF, U+25A0-27BF, U+2800-28FF, U+2921-2922, U+2981, U+29BF, - U+29EB, U+2B00-2BFF, U+4DC0-4DFF, U+FFF9-FFFB, U+10140-1018E, U+10190-1019C, U+101A0, - U+101D0-101FD, U+102E0-102FB, U+10E60-10E7E, U+1D2C0-1D2D3, U+1D2E0-1D37F, U+1F000-1F0FF, - U+1F100-1F1AD, U+1F1E6-1F1FF, U+1F30D-1F30F, U+1F315, U+1F31C, U+1F31E, U+1F320-1F32C, U+1F336, - U+1F378, U+1F37D, U+1F382, U+1F393-1F39F, U+1F3A7-1F3A8, U+1F3AC-1F3AF, U+1F3C2, U+1F3C4-1F3C6, + unicode-range: + U+0001-000C, U+000E-001F, U+007F-009F, U+20DD-20E0, U+20E2-20E4, U+2150-218F, U+2190, U+2192, + U+2194-2199, U+21AF, U+21E6-21F0, U+21F3, U+2218-2219, U+2299, U+22C4-22C6, U+2300-243F, + U+2440-244A, U+2460-24FF, U+25A0-27BF, U+2800-28FF, U+2921-2922, U+2981, U+29BF, U+29EB, + U+2B00-2BFF, U+4DC0-4DFF, U+FFF9-FFFB, U+10140-1018E, U+10190-1019C, U+101A0, U+101D0-101FD, + U+102E0-102FB, U+10E60-10E7E, U+1D2C0-1D2D3, U+1D2E0-1D37F, U+1F000-1F0FF, U+1F100-1F1AD, + U+1F1E6-1F1FF, U+1F30D-1F30F, U+1F315, U+1F31C, U+1F31E, U+1F320-1F32C, U+1F336, U+1F378, + U+1F37D, U+1F382, U+1F393-1F39F, U+1F3A7-1F3A8, U+1F3AC-1F3AF, U+1F3C2, U+1F3C4-1F3C6, U+1F3CA-1F3CE, U+1F3D4-1F3E0, U+1F3ED, U+1F3F1-1F3F3, U+1F3F5-1F3F7, U+1F408, U+1F415, U+1F41F, U+1F426, U+1F43F, U+1F441-1F442, U+1F444, U+1F446-1F449, U+1F44C-1F44E, U+1F453, U+1F46A, U+1F47D, U+1F4A3, U+1F4B0, U+1F4B3, U+1F4B9, U+1F4BB, U+1F4BF, U+1F4C8-1F4CB, U+1F4D6, U+1F4DA, @@ -247,8 +253,9 @@ font-display: swap; src: url(data:font/woff2;base64,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) format("woff2"); - unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, - U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; + unicode-range: + U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, + U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; } /* latin-ext */ @font-face { @@ -259,8 +266,9 @@ font-display: swap; src: url(data:font/woff2;base64,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) format("woff2"); - unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, - U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; + unicode-range: + U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, + U+2113, U+2C60-2C7F, U+A720-A7FF; } /* latin */ @font-face { @@ -271,9 +279,9 @@ font-display: swap; src: url(data:font/woff2;base64,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) format("woff2"); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, - U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, - U+FFFD; + unicode-range: + U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, + U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; } /* cyrillic-ext */ @@ -340,14 +348,15 @@ font-display: swap; src: url(data:font/woff2;base64,d09GMgABAAAAADBMAA8AAAAAWiQAAC/uAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGk4bh2wchgQGYD9TVEFUWgCCFBEQCoGFJOtTC4NUAAE2AiQDhyQEIAWEYAeKDxt7SkUHWrcDICqpLRVFmSR9YxTli5PK/j8mN8bUHhTb2gPGrLQS22or4keDZ5zWETuc+GN0EJPKO3LS0ZZTt644zRmoSPxwWfR1sDJvRa0l3A+3sZSe4+j5zF6+CDceI2LYTKrsCI19kjs8uOtfU+fMHSkiK1nJCCXaGoSkSNY+QpyRm8Y8N6ZxY+O65W67vdyd7+a/7dZyQ3NpAEuqst1ix0+gkjzw5RHCNCA1OV29GUNg3NIbdx/+///+f2vvPdc+ff7UnyihBIriNMFGxFFAadQLA74/Hv7Zz933Z6EsFvVQRbSFAS1yiHWYmUuSeSOH0Jdxj/BVglePdJYzK5l2ZyTrHSyaFE2qVuwDNoVA8jRy0ln3HSL6XAABRMxth5qrWQSzDA374LQMTVzTunm9txOaLQFfkn77gCNKFzq7tk1fCSApIqSklXL9/1Aq+Ue7N2l9qYGg8FaPH29cWw+LdcmX/s9mWVrVNb1PMkoLFK3MmBIGoTNnDqLS/w2q/mpRa7xqtTUgLUkmkUHG6ZVBY6DIfBgiRAOmmT0YOiDMAIPELz8IEo4uyS8MibK9g+ftpv/v7UFbcLcDihK9gDNpHSYWpkmY6dLaMe0Kqd4IoRJwCBv973f+u3+dB5LieO1G2hDyRELwFpHcjvm/Xft7Z49bONEvFdpSW4EEL8y6AQSUs8HXzwgEBAAoUBBnnAcAlB6scBA0e7BSL8FqfAZx2DFQJ52KJFjiFPpCiODldXBsYUavImfjLFLtjXNVijauxcTbAQ7cdIBlBEDgE2+Brje2m75qDQP++WDWoKIgmYDQV+Opuumt6pWUC3AOrERHPz6f+UFHBMg8yEcDrVoWDUGgUKN+bOkphXlQR/DivHGDBiwJYBTK5/IGfUgm8rgllA0kSFpgNYNCpjKwbyI16h4BYB4t1AJmXA7ok66xiz3KAKhyaVta3+qWtaCqypuyTScqt3GNbliD3KfDr57F1qk2NasBFAkFkF/xJd7n/zzJw9zJtVyAOo25juZARrMjI9mQVektPrL2LE5T6rKgS1NSm+S1rAAqb1hFDaLPRZkikeUjQQkJEdgPE8JObKgJTUB8gg8mO+IQq4zGJPoQePnZGDUHfkBW+QTeeuG/eOKBW664AgIhbxkITKPjKdfMIVgPugjCXawTavFNZIihWNV1KUKYYWCyAJlbQh60WVAttxRrhY468sRxR0eNWivdFyoXfwRTbNL2eJAvoDhoXA9WaLXIKqT/sHNii1CgJVIcELXaJg8OjY3HXgsiax4uIbDkXpwm8yB/fIJNq6zII6kQDbSjdDFNa4RAkgAilsZBqwLkq0W0NulB+NAu7wsRCRONtC80g3JA36DB94Ue4qcCKEBsxQIIOxFAYdsvKddfdc/8ki5sAwIAsi0JdBRA7b2CuZ2v+wLpFDfEDXFI3zRvlEXIwiZ0oFWJnTEQrWE3Pe2wHb8DBireZRfxIRjiHoHvzY6ApGceffMZeNYNELMTjjoz6szwChzwnRPYOYGeGXQaji43gO60+HjGu+V/GHffhd5PI1GGkrWpi5C39mUHMh56pG3qRtBub8rQ4gwSGCQDiPkCLqACxg1dWG0EaicQIuCzBhGIVqOIU2tj6gB84vD7LcaNa0juge+lKMj4CG6Cb8OMWo+A4vl1xNl+JuL9BQuAP1KqOAyShdMDAOS/yLVg9S2PbN9jl+uEk4jY3kJelcBN+kcGZcYZn/UGk2MX3EQ/d9DNxH78sZc8Jg3l9UB3+4xmj7fQ/iBdTH2suRwKq0OBEYC7q447bZLnN1ymVi3V+iTfUwuAjsn9gEOW0HqPPLVzBIdXd2J5bDJpX05/mFTyy/tnt8Fp3sICpwBnXzRGD7ThTwDuV7d9tgCof2gJQN4AAPD68gUAzuAgRZCFntML9HYnBgwDUDUzEhh4aue08A0oDCtIsDgKDcc1woHI7ZAsdMKVcmBHqRjUJiWIicMDEPqHrMDaV/QY1GuDNmuH9uqu7zAYDAXbuLau8+v6uvOTjw+Yi3kw71jFPoZ4iP9RHrNWF2yixDM7nxwK04N1rcG1V8+d+SWUv1fLv68Tz9d8OmifXpXLw3Ji/m+enu/Nz+eZXYk36IAdtvv8uNNmI6se12PplwACBkEA2B7ENwR6lp4WvXpT3WAGiVw8RW6/o3F88rk0yubywwACwABkAGpQ4hKyHQHVYX2GOvScQrJQEh1iq7uWqINQeBVM/VvBT/9Q1HIt+whFhYuwKawIU9uBcHFIHspsU5pl23wp6JA9MLog7oLoy/6dEIvmBohGWmkDELB2oCz3cBTGUg6Xsjk+eTV79rIjdUkRZd/p+GPtCmNnZ2EjKPeyLXOf2Man5qpLv4exmrSiJLiGQ5u0urumGAgZCtrWue/ShutD1/IBwa5p3T97QBKGfeASmooCvZRWLp9GT0S66IwJW153bbvyp33LSmXn/LOrk03u6zZgM99o/WxuUg0yAxBKSc4sVM/4wNgBCw68qYylLGcOZ9eLMV+Je4vr6CFnIyEloQLamGFGz7l8UvEZKNZtHUeONrdNbF4UfjKR/hk3mFsTYtYG9eCRWAQayJXfYgqIShQsvCc8an51pHjlfKJofMI8ILqHjYEKIuX1W4gh0zLrT5dEzatTEfxFhSqFbxBjzDP9SVRMN94XE/c6hy2j/VPclqb5kXEIM78oKmwb0xvabiiUleqpIH9kVuJm0voQIV4OFhI/jcP2UrSYCgMpbRGyZZa//7LGqJ6+EdFGFyI9dWQkUqiJMLtjfq3aDgqaAQycUpKUlxJPtZFYcregzA87ptXEzpQDq9LwszQHWTKr+uDKM8HnlLcHugU5CEWNEhEKbWGXmUPQiiwHhauGlv/OLan6DKpWpOw84WyapnDeU058XTZv4qhBM1yTNkrN5VmgWivqsGwBepTr7Yg4VgsymSiiOxGBoY2M0WCdauKHF9ABhUC2376AhaF40IJXZzQq9Jn2OPIV8ghz7D5JKXow/H0iHpPmsJhuiAK//S7oQca3aP/5B+aQdSY38F7hCAhv5M37Aqx0Tgrw7DfoB9qa09h4vCOvBzeIokbafKSMBTSlCPlUwBRD2+KrIjp2vJ0qMXViEs7/Sfc9ieTsyaXFhbc5HDgD+is6oq8dmraVqV3pHyUNKMYs6F+zQqG8GgmXoW2LGrzantgUDxxF3BGX6X1UXLurGwCp7J5X3mqRUMWxSdh2K2yE82TMJdZREyTzUgG9u2/fbzkvtR3ufs9Qd5U31HtJot+cvE2BKiQf05lQk02GWGpjLfMKuwjzUsQNJdnM0Zs0aMTXNf1JZVErRcPNW5yu0to411KeDWOO9qjf1QCDXAMTPlBR/BVRd6eHHJuszbHUIKul4FR9Z9f6H9c4GndT1iSjIec7SWbvz6OZUprbxWssYwcKaTO/s73AgaOQNOwwy10p9bs06HNvwF0ZcGZTZcitTehO3yT3dxIGnRvJaRgY0cg5zYvJdb+bN9GTsySrQd9ipSpQSkK2DvUDn3mYiChd2fW/uM6JsKgCWWZatYMKxdsGtK/lbz+3oyodtidDb1sJNt1kp6qD/zcuOUO12cXY4lyHzqrEFY4HghgMPHBamH7AFQTvEuWN9TZAVappjHS9ut2/dhUCXh3PnG49TvD+q5IZ/LOOeMtnmRN1VEwkYV6wg1zlq7QZuhCbAGBLy2nmMUdbdCtB6x3aJFKnRjupZJcjzy7c4HphJpk9P2WbOfPMeent8EqP1nxFwjsq3JRovFiyKw0TDCmD1OEm9h9WOJGrlR3OwpgF8/SqGr2XkCJ5xM671FCWYJvJGkmullTUwedHYCbi/J+wMWqH4nhb4NndBCAVaAj5uKi4A9iQ1GLRdVxKK7ygVqmi0fyEBhjILgjqpKtU2PYJGaWfZ/Yi5ZvD0jjPWSvdB45m0aw4khyMZ5vdm1LneVZmbP94YZuzOZK0Sz1KR1SjzStjhyV3Xhvaqpbg0YP8mRt/9Jr4L6EHXff3gR1LaQ4yx6JMJzzBDVJFNE2G8kYOe04jwedy/6cnUDy2VSPAQJkK/jrYeLph2cEcftYCaiZYhA9EkD+POvtOPWLTQAWm3j6iOt2XXHQdEUW8r08bNsKvhDJWmGbvWFtNNOjBsMyYRhyMPst1WEsMTiUp8gmI22ePaZUFCOAX2Nx7LxiJC7UavZPINAGpslS1wpadumVeRMNlCVZW/bWVsLMWrc6jBysOYow4uPHugi/M1GB1AHnmvvR2YhLrvskrXviAKY3nR1hqCzsXiguYYeVXaOgv1S+pd54op04iOWwi+dw2VilboCfNCDiYZwiIj+6uLPrhZCTG8tQQXRiiB0ZaOTWcusHBWr4nGrNqWe1OhbASmOSGpJESQ7R6cBhXJdhtbGBPfdED5aqBIuvKs5gqQY2rlpaRNJFTjgj/mTNEfBQ3zB4mH7tjhgXRTmb2S6XZQ7veDylHqWhL/+FvxJBqrqu2UoDxCZvEOWzAR6m+LAKxXIaZK+peI4acXPSwx4q22KqgcJEm3m01PYnz2I+Cuzt/UPGJ4YX1KCi7yEPy2klegNLjLqNVxRWpjszgnw/7olIpLieoU0ML4VDElLf+j2Ctm1NjKYJuGunCgWQL8WfoRrVmJBy2bV+Ex0/P1pRjOd/ilZSjUrRl///sPN3HVz8Z2gHUxRJfculGlx2YS3yP2pWJOce8uKK5tlZwjyMGkv+9oWVtg1JKZzGMK2msuwXaLj4QrtMz4DbCOpSuw+qumWwj9OtZNDEdDAAy3QHiAk2I8Ii0M5AcHgdk6wOmMYrRzyHYECtwlr79vwSChVDFcZMmr7xz2hpJmf6XbDsHPXYHHe4mZze6dK9ArUuS6rujCa8L5E2rmvOE5IYkNxp3u2Qi1oUktrcDd9OSCsF0oXTZR5NwV8vgrRwNVR8TnOKA3hLpVqkeWemxRK3XVWYdLaekWvkQLzv7fOLkCco/2AKn95cH8ev2i32NPCsmS3j4aNswMjqQaUhKH5dO6mGCtcGqDrNY0WDsfqE+zwiBb4B8BicOq+FlR4Su2x+YXjdtp7Fo0Eg4MPaOWEvhDpT5cnfr8VPEL06gC+NmtqKwLQNCF7rynzOlAPuSOvNOY/3I/ATFidQvS3wn2uN5tP02LRX2hpkBvTWLigu0Wpl2nJPC94nDrqZqVoqK/naZNYL1vTIAuoido+GGjYRR3rzQ9uUwMljkIKQF4l/tQrBYDDs9FWrO/znBoOPL4/PFwOTPXXo7zZs7g7vb+c/frg190fQoyYCz2YtncxLY/W5VSk/97l45U4OLQGsnPsSBWTApGi5xbpRCH9aHpaeYG3u5C7TqW/ij9pI3aA/3Vliz38v8mh7wtCt4vBTpVhi7m6v4F1v/7AuMdD3F8rm7TMWKZ/ARZCkqHiO+GdhO6vDGk5qOPC4URJSzfV5Cr3iw+x5y+k6y+u7G972/Ynlu+nPdhd0/RRvPcPrvHmH2+pOXp32+ywFiwfkW6DUvMQ4lwr+JzkMGrQ2fqBC0K1UFvSeS6/VXLukrh53zknumvUpwGcLFIdyL8GfTNT3VfffOT5lfPkyfHxXq6zB15tRiyRvtqvuOjtu1wFZ7ccfeD/fvb/6s27r78/37Qx/2XSN619bXe2uIRJ+6hnqf2vA9E/77dLOmMOPfbOje2d77sQDu+y4u2B+f16ZqGzlWx7C38KCFrrTkRDiVLYCnlnlh1WUlW1opA2jxyLtszaG6nMjeqhKhLyci3y6PklPQf1wAIUmkbY50T0lzZkZ0KfqtEUlHkpIY/iTZBrFPqiw8XBCgwE8BSPDbHBmhxahqfy071nn187rIkHqXVM0PVZXWITIUZPoNHzdtcciu+iHVaFzkT+26TVSKBpvW8Cu7tgUTGQEISAt8cUW282+h9WP8k+rVIYuD3ix4iE+wdftZkG2nAYTMyOap5sapRvqZbZ0Ch9+9MGWEDEcPuzAfmvNxe523z4sFYZt/2f4CFe0YtwbQdRhLnSX/jxPQmqb2BllWnziVtXzPzGg+/827DP702OHdT0YL+RfebcY+TirmciRFuMdbNuOmJSUcblIJdhpwA7muEBWswH5HdMS5za29B+8smAP8ubtFZUWlrQNhmrgkeWKCeD0nkbH5zPPl6YdCmzuvZBePlqrTz+pOLVxweI+RBkRVFGcJe9rTJJbI3Za67Z0L687Dyi+rr7mluuul+V72Sx5pKcsJDxcOEJYUvytdtNzfX0LmpieVxJZhUv3c2m+Jw18kbHiitw8wTH33+Pr4ltzFm+9xXLHn8Q9XaDosHc40QuE92Afn9wK3zJHWa1lVk13rmp5B1SfKL7ix3Oez3G8FyaQaP6qKn99R2keusVxaExX0vy1S387JimcIGAX12G+pD4a3/JPrCGXIpO/VKfreujPl/EvIRYZ7RCy1l2Dh4YKsy73r1E8fV68sOcHuWpswa/wstbS2JT+jRklThQVLiST7zOAEARE8xYhGr8NtT2J6vwDs8Pn6W5yGNQsktObKDCaWg19WIOlS1DSOPlcMDD1Pq9pVo2T2NOSxcVR8XnaENqmiafVtLrKFxitRFZeXZiSEUIWKaIedf2SMwGQjVw92Jofh78fkB3+/zQsksgIZSg6gDcbWY79PnaWfuByZ+EOdrO+z/4iXEa0GV7ns6WWaAwXKKz3rq59MqwderHvTR5NnKafLU9Qq6VlhIX3ok+n9HE9Vce+ba3uP6vOgQXNM58UIU10HTz07uz1suw1ANLvfn7mfN2unZqZA0sFvKajZi+Tlr0QdMH/GpOFyhDIacYpJx9C8otJjEhO3BCYSCh5kBr+iLbvz+tI6UUBNXg6PfPh3nmcYXkzxvUwFZY/SvQ6k9i6VpLPKGDkm3Ys4iv2TD0aXVt64X9WruITpMR+0mIcUv3D0CU9Fr5RuXzo7W79y49eskf2in70Hmv+B5kNVICDP/YQC/9Fv0Vz22FHBu0M1Ec/f07Tnp0R7TtCpkPQSaQYvW9iHrDZ4qOzFKMpF/i0gODfVMjeV60yfqHXOmoCk5wq7nPOciwYGMNXofFWOEMzX6s5iCYNXhAHaTDHDQD/OqDIudmm5tvHIrHLE1TyzfHxRtkgoqonTDlI0F5YX5qcG+SaUeGcCf9H55MU0aaPv/vLV7AcbyxYmj7rnYOFy98OYyieYQ8v4MyPJ5jvP/zscKXwQlOmb+TvBbZgMkgSvvk8ws0b+rAMI3cUXCZsORkR92iS7diBz8fAB7dOHHwGUCRA65pxF1Ie5D2oL8IoIELrYOUv17N9Z4EMKpH0rw333WvvAd/ta3tcXe3ii/d8qZoip7qrv0S7bvWWLztQWPF7RwXm4uW5RdIrBAqIlSJSDwKqYqiCA0AWFx4QHggOvSV4ccNoZlmLwA/otzsAjSIwnluYDREpzj5KJihfXcoAYAHl9dlOafqdnWfuaIn69bFbyt7Xr3LoEAFyt4LXzbFBDegdZWywbvSOWQzKk1RfZSPoIXcbp8DG9TTbzrHvVQNoJlrqfFsyD0RDLEEuh9D0NP6RF7uMMPUgMQgvXQqLHrYGs7NFWocW2s4i8sTGWYcFCy21Pe/mBBz+89z/YmxC959lK9sPBBU0t+AiZD1e+2K432Ty0gP0Q4Pfp7GGfbsvJu5oW3edu0KKmOs/Jv22jqqQGb7qCU1CVI/elbJBttH6yJjh9cdt8hp4+sveluuF0Z6HpmhO9SlZfbTbDeWedROo3TBzj35aev7JlylUtKmVOexKIKu1v0hybzd7B7jRvcZtwzvaeji9iS9096N7B8ZyFMXw39ypafiatXdlcdfBxxkDZlYASYuasEr/eSxiagPWI9goIi62JSiUUB6wrE68Cb4PG26B8aBsQP9eNrmj5ZNB2CePr/mVXYMO+nq4uVT2d0lWqAcJAHdpSJ0AjdGRTkioLXe3cmprqpHWqVpkKVaB2UmdN1ykm/zHzZMs8ExmBYJJmkWuemnT6r9xarCPOH3Mqt8i0KDBRBtCNlWY55sm1hkISjut5Zinmua0XVdi0O7Ttnj/oBMRykCHE+28y+9nHyVOJoYYBhtwLt4D7Z6lfMtdJqCEH+DoJF/FBKfU84ea7bcDuHOHU+6ugLOYZQP56dvM/gBD9B8wsc53vXzJ99qZv/rX3Efjo2WfqOp0+6z5ENVk3gYAZmmC5ANi1ujwSFSflfLW/kJfNL5CkJVy0BG5DlTMfTp17dTt0Bep3JqvRNS1zDSt5jXr055afqBMIoiQ1QZCw2puDUV6W+DwMtC6qhPXAyhT82ITQ6IzW8nzgaGWRF4msjTIg0FbI1ROvcA7H8qEnmhbWtiXpLP1rXgGkxfxeflqUZzNE6TKYvqNBVrRzaKh4GGSZj7yqVv89c3kp9Jt6sGKL1/vkNwyHWmwEP5dJ6istDu7KjWWn9/jTvRF0woAbgJgffo11QL9zO85XEyTx7/TTTeqiVf4AafE6tNPwciKzimD7SaPqhfa5DGbuWJxVunNoqGwYuN0qXz29QD0z2HsdvrCzuzF/LyGN8FaAH8c1boHWdv89cboF/q5p/b3kilKUegeI8cmVhgO/QTVKTVRv6dmcIOiQr9tDVSd3OVznTHsmmAZSQ9lhsSjw4s3rb5t6sjSL1A5P6SkkaryIjk/CqTaX1eRtu5Tcg07Qo80bbV29y6vCWug7/uvcdPQzRZWVFZtpFHL0wPG1K0/H3sWeKVyDFzIDPEGGOWddiMSVRCVEVjPmPeUn8nJTswRKoUiozEoV5Cr42zVcqN/nY0LOYFS50NVjoszxzvvEtuoktVSaKyIMVRkRAdICOFrIZETZwD6aIiJRrKDS6HKqOFEeAehvAoqN4mfjqSiPCDEtaxvxroqzZWcm3D3/Z5DeEEZZ7oHIeRoZ/A1VzAgRSg4/u1MtjzrdlCOV7lx//MiJQGpRfvTkybv3/duqE9SJ6qwdG4nENr5rfnxgqFguwk/lw5G9wreb2qoYtS7U2m08b6E9UazjAOJ4+dj9jxhR2mvSlmcdGWv0o0HOYzS5gPgm4nLm3fbec6z6BadZnb3cu8sPNUM+a7eu/aRdCvHjHyry7ctiCRKULJ++omKf7qx4gbpgGPg9Kz/yP87haCH0RHN9Qjk+gXrLpEpPiD9FBEjmD89Oo4diVrWX6WcKfuQF+D45RxybzPHqLxzKGgakj29veyJFEkNPWn967ZH/sfb7oR5vbqgdkPnSUHbtUIBkQs6IMqIILZBM3GDmjtbCXPPXbnP+CCDCy61Pu1o5PlNaUIock6L9C3hkouyl12FjVIasPgSEnmCX5a25yV9XOeIowvxJwV8L4CWzAwgOb7NCCrxzCK3J1Jr01bNrLuRMeGR6p04JXLu92TExrjh7D6W/wl3mtkzEqgMLHvvLzN8/RXQ6JCrXUVM2dNp3N27OSnpz6j35OdmeGhcBmFiZ7DW+3SQkn9HoElu9V5QxZhsbxWpZGvdcFNhmNySLvFtnbVHrh8JaVbnfqYus/nsBweLWDPRi7BonbdG8Ikctdi16aXlyU5z5M5nfwvenrNvNWmJRDgbpJiojQcQSa36TdYGVxrQFgSKaa+26b2rfEyywMtASmo1JuZf5IDMlH1MXmvq6/k19CpBxb1SsfTQvyhUptkj7e6WC4dj7zrN8yapRTn4AS3/4E+27KzU1MDzF0gpsKx9HHH/5KvrM91364FbM7iMhcbUZlKhQTqmr8IOwFBPKpUZkxNUcCdk9Q+VarSYTZFVFpSYGpcZVRTICeQ3XkgocFhhNAb3pKZAQ84TKsdzx/8ElxgYlJo3tHCvqTJ8nqcmIoIZySzFbXEM5URRWu0CAzWaic619QutiXV7i6oO4YVVWcvz5hHlW3pRautlLyz8TvLAFVkCvx0XCrRG9pJezGh+v1al2+4iwCUej0e0kTkK8l6/LeBqR6SjDtcu4tQlKWnXF3YgcZu/bXRcLt+LpuKvxaq8aO1JJQgwRc01CSsJmebRLWOrHJR5EWlYk1/n5pB89wMONpoxMc/YOigOmlRoGPzKULIxkxAijyKH8qO5oGw8ji5iIhZVATE/6qaYKkFNAMjUzZUOqq5z+KhCeihZtmX5wkca7isV9x+MT8dyaFdSQjYzClk0NNeFeuYpiXlxOmhxY99/UDNblxfIzJQ4GSkt5OUO9e+khdrMLFXMsyr2ZGM+kBQZ40KIUJeulOZQYDzdTkq8Qt0i5/HF/OGC2yGQvPfuMNzNYqThKeIbPLyQWlgiV46hEgGTGpzWy1JxPAcC2nih8f9QekgjjOB2bNuSEFdR7vQHBFasG+vz8vHx6V7y3eHn2rcDHvFasXDxIypyamZptJQsYfJEgmhwsjBbxhYygQ6f9eOKImPerFXDGZfv/3dhLyVvbk/lEGRFnAFET4J40IZNcCAgql8vSYkVugP2F9HpJbKI6MeqivViRk1p8BBi3WsTJDw2BvYvgeVfEM6XYQA+uE9uD6YR1ajndN3/t6v4cvDs0Gx+PxqJbJgGdrgOqld+CA3ET9lqDPddH7ffpO44f+v1vZMU3582fzy/lVgm8339BDEk1h5qjHF+yIisE4FYknzWyqXnxcnStU5Mq17HJUd1mKiwkoxE6IADvQDBGPfdjLmBT5NyauWJSadWf6sBxu3HA/XJn3oUL757OHXCLhzDhwsmTD+fHItoQsdcBiJy8OP4eYb9S86k9LfJY78afWQdhM9YzE7Bfqu5N4cdS82nHBvq/J4/Cx0daEGt4MU0iKXPJOl4twiontw6xlsdcIhXFNK3hgdws3fTi6Et9i3/S9o9bjR/+FduzJOJC81PMdDWnYZ1fDcoKVbzBJ1FT/RT4iy5WbklPObRkgd9k+RplkHUDvDw9tH0f59WSQ1vNglfcucOfn63mh5dw/+8YU1AWwJutVQGV64jnKhenHNySDooeizJiCO2QIoMAvFdpZCh/2OzT6Y+u9k4/3G9VrRAShcZNLoL6P2+c2612pobQTTBGiRmzfb+rrLM1DIzM8pGEVecFCCp0z9PEpl3NvQM7l1khd1qc2X+oo/rCVG5v5hD6sTURIAOGl1/9qGh/F6b0opTkINHLceSFtXXFInpGpUdc3KfA/KwKmaJMBuLGZba32OgEwn6rXfQYsu1276P2QrshQfjgW5xHn8tiIdLHrsq90zJq8DcgvEAvv0kp8K++k0LYESxJiKLgsWG0GnaqT0342n7WWP7+RW++lgyv+Zi39FJ3e/bEaEUh+m6BMqqO3fdjrX45sqiKK1hWQCWplKFxzOywoKrEvMIuENC05+aW3IVOO7xxjEq0QnMvkI7+wsZMeSxxgYz21/bW1Fjp59nktijzmxsekVsrXnmLcWkP4x3X+GWXFBGDorVB7SDSGZecuM8/lqSMKcQrMGbr2A4cw8U2p4tzDy1qTnm37sGlc2VpWpGeGGqHmU7UXRj5YFx5D7stOjNGofEUm6qt25iUjMQOWacx3jlJVN+ZLHz3IpnInwUZ746cNkMNVf7Mix/pxElTw/Uun3UVBS9gr87DXuS+0mtRl2c/0Zs5g5zJe1LM/EMG1LiIMFKa+dzT24sd+DkjVPmGTgBQjr0umFTPXAVZ4JAU8Ac78sWmaViYtwFfatoDdxIFJqY5Ggeav/3+l65nJywKZqhsYtKN91hQw16Ikc/xGuLlZwAoZeT7+etsRTbCWhRHlf7Z0/9kwCNWzdHk7dvNQOq+FEZ7fY7QWZ9moogmKenxYdn1jEzrTyUIKczMahp7gyXsR1dGxMioiWUpG0dubCnvDIouEEhiJBq8Pu47QqX/ieTn7gIJ1Cks1ezqVGCNc2Tb8Kod0YJKYuWr5r1Zd1+9DfJPAPEZvgdLoFdb23ldnqVmXP3VUbYkxwN1kHeLtq54vagVatRbVNCzDbWt3DOsLGP16FjGKoAfL5fqPBJwSS9ZDkuwkfWlp05JY+X13iIztU0bl5IdmZp41D+elB1Tjs92Ne9kozlGKvNNrNIyysqMb0ttflcCZuPUcs30t6bxoa8Ni38fvDLwx678VPi0Qzwn9yLROVbu15HNE2mKBrUCh+aQokb/VW0rARUue95mjw+sUCT0RRL/9ts27M4Cnabnppclf+iV++d15ywsq6rafVvr9gbdSrKSOG40HpJH23gDC2zlww5urujaolxGa00c0wg+OXNhV9+dporPW45thhgvW2v0n/1/a03/1HW9Pbi73inAWUWO5CqQUtRiBXNDtgTTzUsCxvBCRSWFrXFWxj+0eks68/Pkg7CTLTir59/e70o0jkrRRCU1ouXZdHIeHZ1ZqU23Y7ODfC3O2n05LDEDkUgzgCAX6C9jxPQtXOSFxLTZu3fgkIuvr58zqhpBPbB/sBWBLOv9dpnkSqkIWtYQk68HEBQgH5K5KYhj1oeKhpV/z3b0N/WX4OT6bvK+kua+cx2Zf4eLrA/5jbkpcJGtYZYDfamHsiNoZPtivrutO9+hmE4Op4tE7n2KFRQ7aiuwytJZJxtPAgxpRM/YOsV4ySHLHuBhqfPfp/vA3+4AX3lxiU6av9bnfFG9r17G51XHb5UsXT9axTiWH++6nbu1cdlBYT05L+g1ykpPHFyaFkIOW0Nh+RtLi9xLLfzWxyjEEa2OfVFxPrzAEDmXsyhkp5HsFJcEhs8BvYZNnIgASI37SgD+3DbXz9E+b0fa/3x514n8HDeXh7+7wX+G8//bc5t+KchpuGDKLfYNEJZdTuGtbE+TSXoSIyRkVk8aT9YpTFihSuMNdCQrBD28sLRQXntyatvug7e6cDG8aP/QaB45IIJP9eZH+VLJdFYIQUjFx6SL43xCYnjg5JvgDMumOR+BNZ7iH0f/oZWNbOeUhcjNe+pPtRUeY7KD8Ofs1THg/dX2nDj15Lv7Au7WjVOoerNzQsnR11N83tYN9+HA/uTjkzNl+01OPg6hfx74vFL/xwp8M99qBt4PNKxcGPU2QJM/5AlNc17tl2VffxTgv504qDRuje51bd2/fFHX0fW62CU2tsfRWnwQN43CiEyMTLCl6S8q8MQeAPMGRcKxsYNr+ql3gE3i7caxkhK2QL43BpuvEJUfXrGqeGUUt5ITQuAxQvvEcUp20f6yIvO/p+qcvFeSKQe9PX43wWoIlx09/cRCU4LjWuAdhF48KWpdyb9hpul+3uhIMV4W8bP9xIeivdptQekyXGWkKyIWEe3gscPBmvQ/a9/GflJqcnaaxBOZpJfiGylOyVY0Kqk3h1Dedv+abVl0rSI9Ze0hWd/z0FhSCCU+fzutEzJP4LuQliT2BnXjsudQL/tG46ao4cz/z9b2N62w1hhO3r/rvxmz71HNj8mh0QHZsDOLPftc7m1fb6SJ6EvtypbGNFYvsVnysLzs1M7ucON6+0ZgYx65ddeXe/cHP4wfoZhj5Mv4FX/vuoZ671p/otfr28dLA1yQNx2YepVHUli2ReoI/0JYLKo3PYxVvayrJZm3tIerylmXKhnTygnjuR0HRKiH+Ibjdq62NLZnYFQsNSSYCqwTb+auvY61yj3fS/tBUbtDvJ52IpdiW1wti4f/gaK7pXXvjsG9AdH0qOCQqFB8w3FbrA1NCkyyzhc1skT9HiXFPlHFTBfS2s9Fie82463/fPvDYpqG5PVyVWtwla01LQ+jsL36+24QytiJZGvGvNo/O1OsDme+hd69DTLPSr94ta4TZcS6+0oQu+nkxHQns9pajmXVnaBY7nXscXTPzDTn3/0S/66okPz841nyRo6kxNU5AGeGQ+E5Gne38O7SpycKRA6cvyYD+8a16PM3q7iJFKKgs5fPXRkXxbI9xyUWMLvH19tJ5guNC7WeZ+HBOKDXbc7r5qECPnQ+7z/6KQxt9BrcpjnTfPB5WvWu61uyeurzODgqPv/owzXNq29x645YrIlpXrBueUHSbVY/4WR5+fODTklE36bPSg4kJmT6sPc95wX6HY+ocFjKYxSPA7ExRyb0MqbrMqEaHuNlWmapzq4hpfQDZPzxIJEACzQ48IRDwAsf/CDiD4lgwqBQSC6CrCjuQHGDSaie+v4rthtAg3BQxNbp75rOJeA1HoA1HmYLwJbd8y73qNOzx0YSgzdKuJbqWP+C64Giv3Oqlfxua8X/dFH+7QnkcgCAPzvMM9scRx3zoOPu49Cgmue+DZhtjqOOedBx93FIoFf2tiOBmQbv9vklBQ9BEQs//Ztd/xZ6qtaeibw1vlgnOZQT06Vu0SoMx3sI/jrQN/n5zqrt7Xl5LqfybdyDqxVAek5Gncg2bOQbsk2rBVtS0icL3gO7HFnA+ogJkpBu8o4mEcCBJ5x5bO72i96fH+L1OrBnwqBAmTNAZK5+GTm/C79z3M/4dfmf5u7cttG/FF4ZaYvvNn6E5MKBx/am06uRVCDjViFfgTxanpiyzVa3GhgkvlU5kbrYUyRSjyROUXdV3Xt706lRTuC35/bIwE6fi6TJbNzZz1epo3RiSoZWd84zSHzzESJ1sadIpB5JnKLuqrp3BnZqlBP47XdkBEDRju75N3iPv/O+uzPLX8NuFhj/Of1tvgKT3V72Y2G/qPkogMTP38nvYEV/L7P16dViz+Q+AgFIAAUgwTxFT23qMDa0woPGf/qyExhOi/GHx1RZZ2lN4E0PyQgU2QA8pgtt6oJEIxypSH8k41JJPFyO+1xGtWJCqZXLHXNXruRxbjCc6NgkYbqFBdZ1SD1vKmsByx2wrSq/DXlqoZQluxhpdCFHMD455ktMmxvLEO1GJRt1kYbFfVjkkLGJRxuAXSYBYwJwIsCcgOol5oiO4jLA4kn08C3m/OlzAm5LtIkNOJKGmJRDL1q2PNBCIqJtyFI9XB0N36xEZExJKTkqvkilTFDfZEP9Cr6arzzzKtqAvs+CDfTltPVScLlDk5OzRAIelYV046fymIo1Hz4K+HKd4jgbgpIqrRHyNoECgphVkZqx+DoJGgdMQ4b6gCvgAiQI5MBEjS4Cyb7ljcTqo7jATbVnSHmacUBBYTMF25s0f5VloDUegVLc+oM1q08AA+UEb6FiyqcgQ8iH/4ptn9Sxilz3cnnYQ0cnpsTEXL2jS3mpMAvJIJKF/twrIyg1NPm9ERsorHc2JZy3KC024IbGtI0nbqBE4JReb0/xGHMiKeaBppvQRB5eIvbb21S1dmZ5g+UIyxRKh5KmBVa+wDQtsKXJ3UaRkS6PibkypHxAPyt3FeLKFjXa+i9GfBXXpdZY1pyVkR4UKRVsU7jFvmv/+EKAaMG3Xyq3fAJ2zfLwLco8t25HyEMhzHw5FArl7aEwfiYOhXOw4VAEO60cqRccYiRAyLEgABjwOhQC9GFcJDVA2fV1K+UAXV852rkAEPC5RJ6uJLQ6TLKRoCIHrlo6pcjKiEp1SgclY2kTgRpfVT7uR8xSJSn+VLlyAhAovXdknpYBcJXKM81Vjz0RPdUdioVEUYLyJ59Beqb8tiwpPsuoVczEiDoFA1BPta2ewTT96BRvZT36SlRbg+HPb5yMSlQxtX8ZPl/klCWRnBBESZmBqiGUxbPkxkplewj6KUlRJvfgUf6mdApUGgPAYuWZ4nxu3Kk9ADW4zH95/l7oFQBJIDAAA7+ggTtP/b/QkBFjJkyZMWfBkhVrNmzZsefAkRM0Zy4wXGHhuHGH58ETgRdvPnz5IfJHEiBQkGAhyEJRhAkXIRIVi8NraGpp6+jq6RsYGgEEYxNTM3MLSytrG1s7ewdHJ2JgoFW7IT0hIEiIHgQFZhUG3PPQ/fqQ+RADiCHECGIMMWnarHmLlq1at2nbrn2Hjp2iO3eJ6Rob1617fI+eCb169+nbz+q49U8aMHDQ4CHJQ1NMGIgPq6z0wbBua2zWoVefg/E5YmQqFofX0NQq/5zI0NHVK/+zDAyNAIKxiamZuYWllbWNrZ29g6MTkUSmUGl0BpPF5nB5fME8OgYDhN/JtJuZDJsx+3M5Pa8Xg+pF/uV8zH8ryJPxG5o52I3aOvB2dV0xYvp8tUDSv9h0fA/btPNo8yo/a9HHuq8Z6P/jTzliMLoHSRGR4UBGA1mFBFeNWpGHCEEnzcen0V0RndWUnH9MCRWaqHhOCbkxjxpbxRW5NUnTCb/Y1TCpdrTXXBWJZgpbOAbFs3A84g3kZUh//jk0Uoa3xufw8hJ4oqc84DILunH/UXWRuFJUmrhcEiTVcrlMyazLlAt6US+nK+TDjSysWD1juS1VVHVqOHtHUzmO3M6WubyhQmolly+7VBRSp/OUUnyjdEUcRf3VJWbLLaNQob+jGlwPZBvld3VaTH5JZxd/QuXQV4UyZ8N5HrM2zku8Bpbxgpe0Ml7WevGIpPcdjbDwCo0EUU1yIrIBIz2Gkh6ADUyxgXexkTDKhauUAHAKQBjALgKfEQgAPpvALgKBwGdj6RWyRQ==) format("woff2"); - unicode-range: U+0302-0303, U+0305, U+0307-0308, U+0330, U+0391-03A1, U+03A3-03A9, U+03B1-03C9, - U+03D1, U+03D5-03D6, U+03F0-03F1, U+03F4-03F5, U+2034-2037, U+2057, U+20D0-20DC, U+20E1, - U+20E5-20EF, U+2102, U+210A-210E, U+2110-2112, U+2115, U+2119-211D, U+2124, U+2128, U+212C-212D, - U+212F-2131, U+2133-2138, U+213C-2140, U+2145-2149, U+2190, U+2192, U+2194-21AE, U+21B0-21E5, - U+21F1-21F2, U+21F4-2211, U+2213-2214, U+2216-22FF, U+2308-230B, U+2310, U+2319, U+231C-2321, - U+2336-237A, U+237C, U+2395, U+239B-23B6, U+23D0, U+23DC-23E1, U+2474-2475, U+25AF, U+25B3, - U+25B7, U+25BD, U+25C1, U+25CA, U+25CC, U+25FB, U+266D-266F, U+27C0-27FF, U+2900-2AFF, - U+2B0E-2B11, U+2B30-2B4C, U+2BFE, U+FF5B, U+FF5D, U+1D400-1D7FF, U+1EE00-1EEFF; + unicode-range: + U+0302-0303, U+0305, U+0307-0308, U+0330, U+0391-03A1, U+03A3-03A9, U+03B1-03C9, U+03D1, + U+03D5-03D6, U+03F0-03F1, U+03F4-03F5, U+2034-2037, U+2057, U+20D0-20DC, U+20E1, U+20E5-20EF, + U+2102, U+210A-210E, U+2110-2112, U+2115, U+2119-211D, U+2124, U+2128, U+212C-212D, U+212F-2131, + U+2133-2138, U+213C-2140, U+2145-2149, U+2190, U+2192, U+2194-21AE, U+21B0-21E5, U+21F1-21F2, + U+21F4-2211, U+2213-2214, U+2216-22FF, U+2308-230B, U+2310, U+2319, U+231C-2321, U+2336-237A, + U+237C, U+2395, U+239B-23B6, U+23D0, U+23DC-23E1, U+2474-2475, U+25AF, U+25B3, U+25B7, U+25BD, + U+25C1, U+25CA, U+25CC, U+25FB, U+266D-266F, U+27C0-27FF, U+2900-2AFF, U+2B0E-2B11, U+2B30-2B4C, + U+2BFE, U+FF5B, U+FF5D, U+1D400-1D7FF, U+1EE00-1EEFF; } /* symbols */ @font-face { @@ -358,13 +367,14 @@ font-display: swap; src: url(data:font/woff2;base64,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) format("woff2"); - unicode-range: U+0001-000C, U+000E-001F, U+007F-009F, U+20DD-20E0, U+20E2-20E4, U+2150-218F, - U+2190, U+2192, U+2194-2199, U+21AF, U+21E6-21F0, U+21F3, U+2218-2219, U+2299, U+22C4-22C6, - U+2300-243F, U+2440-244A, U+2460-24FF, U+25A0-27BF, U+2800-28FF, U+2921-2922, U+2981, U+29BF, - U+29EB, U+2B00-2BFF, U+4DC0-4DFF, U+FFF9-FFFB, U+10140-1018E, U+10190-1019C, U+101A0, - U+101D0-101FD, U+102E0-102FB, U+10E60-10E7E, U+1D2C0-1D2D3, U+1D2E0-1D37F, U+1F000-1F0FF, - U+1F100-1F1AD, U+1F1E6-1F1FF, U+1F30D-1F30F, U+1F315, U+1F31C, U+1F31E, U+1F320-1F32C, U+1F336, - U+1F378, U+1F37D, U+1F382, U+1F393-1F39F, U+1F3A7-1F3A8, U+1F3AC-1F3AF, U+1F3C2, U+1F3C4-1F3C6, + unicode-range: + U+0001-000C, U+000E-001F, U+007F-009F, U+20DD-20E0, U+20E2-20E4, U+2150-218F, U+2190, U+2192, + U+2194-2199, U+21AF, U+21E6-21F0, U+21F3, U+2218-2219, U+2299, U+22C4-22C6, U+2300-243F, + U+2440-244A, U+2460-24FF, U+25A0-27BF, U+2800-28FF, U+2921-2922, U+2981, U+29BF, U+29EB, + U+2B00-2BFF, U+4DC0-4DFF, U+FFF9-FFFB, U+10140-1018E, U+10190-1019C, U+101A0, U+101D0-101FD, + U+102E0-102FB, U+10E60-10E7E, U+1D2C0-1D2D3, U+1D2E0-1D37F, U+1F000-1F0FF, U+1F100-1F1AD, + U+1F1E6-1F1FF, U+1F30D-1F30F, U+1F315, U+1F31C, U+1F31E, U+1F320-1F32C, U+1F336, U+1F378, + U+1F37D, U+1F382, U+1F393-1F39F, U+1F3A7-1F3A8, U+1F3AC-1F3AF, U+1F3C2, U+1F3C4-1F3C6, U+1F3CA-1F3CE, U+1F3D4-1F3E0, U+1F3ED, U+1F3F1-1F3F3, U+1F3F5-1F3F7, U+1F408, U+1F415, U+1F41F, U+1F426, U+1F43F, U+1F441-1F442, U+1F444, U+1F446-1F449, U+1F44C-1F44E, U+1F453, U+1F46A, U+1F47D, U+1F4A3, U+1F4B0, U+1F4B3, U+1F4B9, U+1F4BB, U+1F4BF, U+1F4C8-1F4CB, U+1F4D6, U+1F4DA, @@ -386,8 +396,9 @@ font-display: swap; src: url(data:font/woff2;base64,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) format("woff2"); - unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, - U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; + unicode-range: + U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, + U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; } /* latin-ext */ @font-face { @@ -398,8 +409,9 @@ font-display: swap; src: url(data:font/woff2;base64,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) format("woff2"); - unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, - U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; + unicode-range: + U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, + U+2113, U+2C60-2C7F, U+A720-A7FF; } /* latin */ @font-face { @@ -410,9 +422,9 @@ font-display: swap; src: url(data:font/woff2;base64,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) format("woff2"); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, - U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, - U+FFFD; + unicode-range: + U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, + U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; } /* cyrillic-ext */ @@ -463,8 +475,9 @@ font-display: swap; src: url(data:font/woff2;base64,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) format("woff2"); - unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, - U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; + unicode-range: + U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, + U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; } /* latin-ext */ @font-face { @@ -474,8 +487,9 @@ font-display: swap; src: url(data:font/woff2;base64,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) format("woff2"); - unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, - U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; + unicode-range: + U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, + U+2113, U+2C60-2C7F, U+A720-A7FF; } /* latin */ @font-face { @@ -485,7 +499,7 @@ font-display: swap; src: url(data:font/woff2;base64,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) format("woff2"); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, - U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, - U+FFFD; + unicode-range: + U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, + U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; } diff --git a/apps/web/src/scss/variables.scss b/apps/web/src/scss/variables.scss index b3a27a7824b..4b023e12746 100644 --- a/apps/web/src/scss/variables.scss +++ b/apps/web/src/scss/variables.scss @@ -20,8 +20,9 @@ $theme-colors: ( $body-bg: $white; $body-color: #333333; -$font-family-sans-serif: "DM Sans", "Helvetica Neue", Helvetica, Arial, sans-serif, - "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; +$font-family-sans-serif: + "DM Sans", "Helvetica Neue", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", + "Segoe UI Symbol"; $h1-font-size: 1.7rem; $h2-font-size: 1.3rem; diff --git a/libs/components/src/variables.scss b/libs/components/src/variables.scss index d278746bb2e..bc9cded4981 100644 --- a/libs/components/src/variables.scss +++ b/libs/components/src/variables.scss @@ -20,8 +20,9 @@ $theme-colors: ( $body-bg: $white; $body-color: #333333; -$font-family-sans-serif: "DM Sans", "Helvetica Neue", Helvetica, Arial, sans-serif, - "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; +$font-family-sans-serif: + "DM Sans", "Helvetica Neue", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", + "Segoe UI Symbol"; $h1-font-size: 1.7rem; $h2-font-size: 1.3rem; diff --git a/package-lock.json b/package-lock.json index dcfc0c475bc..671951c0349 100644 --- a/package-lock.json +++ b/package-lock.json @@ -159,7 +159,7 @@ "nx": "20.8.0", "postcss": "8.5.1", "postcss-loader": "8.1.1", - "prettier": "3.4.2", + "prettier": "3.5.3", "prettier-plugin-tailwindcss": "0.6.11", "process": "0.11.10", "remark-gfm": "4.0.0", @@ -30918,9 +30918,9 @@ } }, "node_modules/prettier": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz", - "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz", + "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", "dev": true, "license": "MIT", "bin": { diff --git a/package.json b/package.json index ad30bae428f..bc00ac57a59 100644 --- a/package.json +++ b/package.json @@ -121,7 +121,7 @@ "nx": "20.8.0", "postcss": "8.5.1", "postcss-loader": "8.1.1", - "prettier": "3.4.2", + "prettier": "3.5.3", "prettier-plugin-tailwindcss": "0.6.11", "process": "0.11.10", "remark-gfm": "4.0.0", From d43e4757dfcb3f7851c9c8e6bca180302d382315 Mon Sep 17 00:00:00 2001 From: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> Date: Tue, 29 Apr 2025 17:25:27 -0500 Subject: [PATCH 02/19] [PM-7604] Require target UserID for KdfConfigService (#14380) * Require userId for KdfConfigService * Update auth team callers * Update tools team callers --- apps/cli/src/auth/commands/login.command.ts | 28 +-- .../settings/change-password.component.ts | 13 +- .../change-kdf/change-kdf.component.ts | 8 +- .../components/change-password.component.ts | 7 +- .../components/update-password.component.ts | 6 +- .../update-temp-password.component.ts | 7 +- .../pin/pin.service.implementation.ts | 4 +- .../user-verification.service.ts | 4 +- .../src/abstractions/kdf-config.service.ts | 2 +- .../src/kdf-config.service.spec.ts | 162 +++++++++--------- libs/key-management/src/kdf-config.service.ts | 8 +- .../src/services/base-vault-export.service.ts | 9 +- .../individual-vault-export.service.ts | 33 ++-- .../src/services/org-vault-export.service.ts | 22 ++- 14 files changed, 171 insertions(+), 142 deletions(-) diff --git a/apps/cli/src/auth/commands/login.command.ts b/apps/cli/src/auth/commands/login.command.ts index 8d66a566038..8a94cc4175a 100644 --- a/apps/cli/src/auth/commands/login.command.ts +++ b/apps/cli/src/auth/commands/login.command.ts @@ -5,7 +5,7 @@ import * as http from "http"; import { OptionValues } from "commander"; import * as inquirer from "inquirer"; import Separator from "inquirer/lib/objects/separator"; -import { firstValueFrom, map, switchMap } from "rxjs"; +import { firstValueFrom, map } from "rxjs"; import { LoginStrategyServiceAbstraction, @@ -29,7 +29,6 @@ import { TokenTwoFactorRequest } from "@bitwarden/common/auth/models/request/ide import { PasswordRequest } from "@bitwarden/common/auth/models/request/password.request"; import { TwoFactorEmailRequest } from "@bitwarden/common/auth/models/request/two-factor-email.request"; import { UpdateTempPasswordRequest } from "@bitwarden/common/auth/models/request/update-temp-password.request"; -import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { ClientType } from "@bitwarden/common/enums"; import { CryptoFunctionService } from "@bitwarden/common/key-management/crypto/abstractions/crypto-function.service"; import { KeyConnectorService } from "@bitwarden/common/key-management/key-connector/abstractions/key-connector.service"; @@ -40,6 +39,7 @@ import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength"; +import { UserId } from "@bitwarden/common/types/guid"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { KdfConfigService, KeyService } from "@bitwarden/key-management"; @@ -367,9 +367,9 @@ export class LoginCommand { clientSecret == null ) { if (response.forcePasswordReset === ForceSetPasswordReason.AdminForcePasswordReset) { - return await this.updateTempPassword(); + return await this.updateTempPassword(response.userId); } else if (response.forcePasswordReset === ForceSetPasswordReason.WeakMasterPassword) { - return await this.updateWeakPassword(password); + return await this.updateWeakPassword(response.userId, password); } } @@ -431,7 +431,7 @@ export class LoginCommand { return Response.success(res); } - private async updateWeakPassword(currentPassword: string) { + private async updateWeakPassword(userId: UserId, currentPassword: string) { // If no interaction available, alert user to use web vault if (!this.canInteract) { await this.logoutCallback(); @@ -448,6 +448,7 @@ export class LoginCommand { try { const { newPasswordHash, newUserKey, hint } = await this.collectNewMasterPasswordDetails( + userId, "Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now.", ); @@ -469,7 +470,7 @@ export class LoginCommand { } } - private async updateTempPassword() { + private async updateTempPassword(userId: UserId) { // If no interaction available, alert user to use web vault if (!this.canInteract) { await this.logoutCallback(); @@ -486,6 +487,7 @@ export class LoginCommand { try { const { newPasswordHash, newUserKey, hint } = await this.collectNewMasterPasswordDetails( + userId, "An organization administrator recently changed your master password. In order to access the vault, you must update your master password now.", ); @@ -510,10 +512,12 @@ export class LoginCommand { * Collect new master password and hint from the CLI. The collected password * is validated against any applicable master password policies, a new master * key is generated, and we use it to re-encrypt the user key + * @param userId - User ID of the account * @param prompt - Message that is displayed during the initial prompt * @param error */ private async collectNewMasterPasswordDetails( + userId: UserId, prompt: string, error?: string, ): Promise<{ @@ -539,11 +543,12 @@ export class LoginCommand { // Master Password Validation if (masterPassword == null || masterPassword === "") { - return this.collectNewMasterPasswordDetails(prompt, "Master password is required.\n"); + return this.collectNewMasterPasswordDetails(userId, prompt, "Master password is required.\n"); } if (masterPassword.length < Utils.minimumPasswordLength) { return this.collectNewMasterPasswordDetails( + userId, prompt, `Master password must be at least ${Utils.minimumPasswordLength} characters long.\n`, ); @@ -556,10 +561,7 @@ export class LoginCommand { ); const enforcedPolicyOptions = await firstValueFrom( - this.accountService.activeAccount$.pipe( - getUserId, - switchMap((userId) => this.policyService.masterPasswordPolicyOptions$(userId)), - ), + this.policyService.masterPasswordPolicyOptions$(userId), ); // Verify master password meets policy requirements @@ -572,6 +574,7 @@ export class LoginCommand { ) ) { return this.collectNewMasterPasswordDetails( + userId, prompt, "Your new master password does not meet the policy requirements.\n", ); @@ -589,6 +592,7 @@ export class LoginCommand { // Re-type Validation if (masterPassword !== masterPasswordRetype) { return this.collectNewMasterPasswordDetails( + userId, prompt, "Master password confirmation does not match.\n", ); @@ -601,7 +605,7 @@ export class LoginCommand { message: "Master Password Hint (optional):", }); const masterPasswordHint = hint.input; - const kdfConfig = await this.kdfConfigService.getKdfConfig(); + const kdfConfig = await this.kdfConfigService.getKdfConfig(userId); // Create new key and hash new password const newMasterKey = await this.keyService.makeMasterKey( diff --git a/apps/web/src/app/auth/settings/change-password.component.ts b/apps/web/src/app/auth/settings/change-password.component.ts index d8e371fd36b..ffa5247ad08 100644 --- a/apps/web/src/app/auth/settings/change-password.component.ts +++ b/apps/web/src/app/auth/settings/change-password.component.ts @@ -310,13 +310,16 @@ export class ChangePasswordComponent newMasterKey: MasterKey, newUserKey: [UserKey, EncString], ) { - const masterKey = await this.keyService.makeMasterKey( - this.currentMasterPassword, - await firstValueFrom(this.accountService.activeAccount$.pipe(map((a) => a?.email))), - await this.kdfConfigService.getKdfConfig(), + const [userId, email] = await firstValueFrom( + this.accountService.activeAccount$.pipe(map((a) => [a?.id, a?.email])), + ); + + const masterKey = await this.keyService.makeMasterKey( + this.currentMasterPassword, + email, + await this.kdfConfigService.getKdfConfig(userId), ); - const userId = await firstValueFrom(getUserId(this.accountService.activeAccount$)); const newLocalKeyHash = await this.keyService.hashMasterKey( this.masterPassword, newMasterKey, diff --git a/apps/web/src/app/auth/settings/security/change-kdf/change-kdf.component.ts b/apps/web/src/app/auth/settings/security/change-kdf/change-kdf.component.ts index 3c392795ef4..cbbef0e016b 100644 --- a/apps/web/src/app/auth/settings/security/change-kdf/change-kdf.component.ts +++ b/apps/web/src/app/auth/settings/security/change-kdf/change-kdf.component.ts @@ -2,8 +2,10 @@ // @ts-strict-ignore import { Component, OnDestroy, OnInit } from "@angular/core"; import { FormBuilder, FormControl, ValidatorFn, Validators } from "@angular/forms"; -import { Subject, takeUntil } from "rxjs"; +import { Subject, firstValueFrom, takeUntil } from "rxjs"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { DialogService } from "@bitwarden/components"; import { KdfConfigService, @@ -43,6 +45,7 @@ export class ChangeKdfComponent implements OnInit, OnDestroy { constructor( private dialogService: DialogService, private kdfConfigService: KdfConfigService, + private accountService: AccountService, private formBuilder: FormBuilder, ) { this.kdfOptions = [ @@ -52,7 +55,8 @@ export class ChangeKdfComponent implements OnInit, OnDestroy { } async ngOnInit() { - this.kdfConfig = await this.kdfConfigService.getKdfConfig(); + const userId = await firstValueFrom(getUserId(this.accountService.activeAccount$)); + this.kdfConfig = await this.kdfConfigService.getKdfConfig(userId); this.formGroup.get("kdf").setValue(this.kdfConfig.kdfType); this.setFormControlValues(this.kdfConfig); diff --git a/libs/angular/src/auth/components/change-password.component.ts b/libs/angular/src/auth/components/change-password.component.ts index 3b186a7fd2e..ca81f741b23 100644 --- a/libs/angular/src/auth/components/change-password.component.ts +++ b/libs/angular/src/auth/components/change-password.component.ts @@ -83,11 +83,12 @@ export class ChangePasswordComponent implements OnInit, OnDestroy { return; } - const email = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.email)), + const [userId, email] = await firstValueFrom( + this.accountService.activeAccount$.pipe(map((a) => [a?.id, a?.email])), ); + if (this.kdfConfig == null) { - this.kdfConfig = await this.kdfConfigService.getKdfConfig(); + this.kdfConfig = await this.kdfConfigService.getKdfConfig(userId); } // Create new master key diff --git a/libs/angular/src/auth/components/update-password.component.ts b/libs/angular/src/auth/components/update-password.component.ts index 77e854753d7..47affbecdf2 100644 --- a/libs/angular/src/auth/components/update-password.component.ts +++ b/libs/angular/src/auth/components/update-password.component.ts @@ -2,6 +2,7 @@ // @ts-strict-ignore import { Directive } from "@angular/core"; import { Router } from "@angular/router"; +import { firstValueFrom } from "rxjs"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options"; @@ -10,6 +11,7 @@ import { MasterPasswordApiService } from "@bitwarden/common/auth/abstractions/ma import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { VerificationType } from "@bitwarden/common/auth/enums/verification-type"; import { PasswordRequest } from "@bitwarden/common/auth/models/request/password.request"; +import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { Verification } from "@bitwarden/common/auth/types/verification"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; @@ -96,8 +98,8 @@ export class UpdatePasswordComponent extends BaseChangePasswordComponent { }); return false; } - - this.kdfConfig = await this.kdfConfigService.getKdfConfig(); + const userId = await firstValueFrom(getUserId(this.accountService.activeAccount$)); + this.kdfConfig = await this.kdfConfigService.getKdfConfig(userId); return true; } diff --git a/libs/angular/src/auth/components/update-temp-password.component.ts b/libs/angular/src/auth/components/update-temp-password.component.ts index 267beb2b822..db2f319998a 100644 --- a/libs/angular/src/auth/components/update-temp-password.component.ts +++ b/libs/angular/src/auth/components/update-temp-password.component.ts @@ -110,10 +110,11 @@ export class UpdateTempPasswordComponent extends BaseChangePasswordComponent imp } async setupSubmitActions(): Promise { - this.email = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.email)), + const [userId, email] = await firstValueFrom( + this.accountService.activeAccount$.pipe(map((a) => [a?.id, a?.email])), ); - this.kdfConfig = await this.kdfConfigService.getKdfConfig(); + this.email = email; + this.kdfConfig = await this.kdfConfigService.getKdfConfig(userId); return true; } diff --git a/libs/auth/src/common/services/pin/pin.service.implementation.ts b/libs/auth/src/common/services/pin/pin.service.implementation.ts index c0034020de8..4e363063f2f 100644 --- a/libs/auth/src/common/services/pin/pin.service.implementation.ts +++ b/libs/auth/src/common/services/pin/pin.service.implementation.ts @@ -172,7 +172,7 @@ export class PinService implements PinServiceAbstraction { const email = await firstValueFrom( this.accountService.accounts$.pipe(map((accounts) => accounts[userId].email)), ); - const kdfConfig = await this.kdfConfigService.getKdfConfig(); + const kdfConfig = await this.kdfConfigService.getKdfConfig(userId); const pinKey = await this.makePinKey(pin, email, kdfConfig); return await this.encryptService.wrapSymmetricKey(userKey, pinKey); @@ -293,7 +293,7 @@ export class PinService implements PinServiceAbstraction { const email = await firstValueFrom( this.accountService.accounts$.pipe(map((accounts) => accounts[userId].email)), ); - const kdfConfig = await this.kdfConfigService.getKdfConfig(); + const kdfConfig = await this.kdfConfigService.getKdfConfig(userId); const userKey: UserKey = await this.decryptUserKey( userId, diff --git a/libs/common/src/auth/services/user-verification/user-verification.service.ts b/libs/common/src/auth/services/user-verification/user-verification.service.ts index 1ff629114ab..cfa6800deed 100644 --- a/libs/common/src/auth/services/user-verification/user-verification.service.ts +++ b/libs/common/src/auth/services/user-verification/user-verification.service.ts @@ -117,7 +117,7 @@ export class UserVerificationService implements UserVerificationServiceAbstracti masterKey = await this.keyService.makeMasterKey( verification.secret, email, - await this.kdfConfigService.getKdfConfig(), + await this.kdfConfigService.getKdfConfig(userId), ); } request.masterPasswordHash = alreadyHashed @@ -186,7 +186,7 @@ export class UserVerificationService implements UserVerificationServiceAbstracti throw new Error("Email is required. Cannot verify user by master password."); } - const kdfConfig = await this.kdfConfigService.getKdfConfig(); + const kdfConfig = await this.kdfConfigService.getKdfConfig(userId); if (!kdfConfig) { throw new Error("KDF config is required. Cannot verify user by master password."); } diff --git a/libs/key-management/src/abstractions/kdf-config.service.ts b/libs/key-management/src/abstractions/kdf-config.service.ts index 9cc39561aa8..c6c4e5d4fb0 100644 --- a/libs/key-management/src/abstractions/kdf-config.service.ts +++ b/libs/key-management/src/abstractions/kdf-config.service.ts @@ -6,6 +6,6 @@ import { KdfConfig } from "../models/kdf-config"; export abstract class KdfConfigService { abstract setKdfConfig(userId: UserId, KdfConfig: KdfConfig): Promise; - abstract getKdfConfig(): Promise; + abstract getKdfConfig(userId: UserId): Promise; abstract getKdfConfig$(userId: UserId): Observable; } diff --git a/libs/key-management/src/kdf-config.service.spec.ts b/libs/key-management/src/kdf-config.service.spec.ts index 986d7abac40..97684266f5d 100644 --- a/libs/key-management/src/kdf-config.service.spec.ts +++ b/libs/key-management/src/kdf-config.service.spec.ts @@ -26,90 +26,94 @@ describe("KdfConfigService", () => { sutKdfConfigService = new DefaultKdfConfigService(fakeStateProvider); }); - it("setKdfConfig(): should set the PBKDF2KdfConfig config", async () => { - const kdfConfig: KdfConfig = new PBKDF2KdfConfig(500_000); - await sutKdfConfigService.setKdfConfig(mockUserId, kdfConfig); - expect(fakeStateProvider.mock.setUserState).toHaveBeenCalledWith( - KDF_CONFIG, - kdfConfig, - mockUserId, - ); + describe("setKdfConfig", () => { + it("sets the PBKDF2KdfConfig config", async () => { + const kdfConfig: KdfConfig = new PBKDF2KdfConfig(500_000); + await sutKdfConfigService.setKdfConfig(mockUserId, kdfConfig); + expect(fakeStateProvider.mock.setUserState).toHaveBeenCalledWith( + KDF_CONFIG, + kdfConfig, + mockUserId, + ); + }); + + it("sets the Argon2KdfConfig config", async () => { + const kdfConfig: KdfConfig = new Argon2KdfConfig(2, 63, 3); + await sutKdfConfigService.setKdfConfig(mockUserId, kdfConfig); + expect(fakeStateProvider.mock.setUserState).toHaveBeenCalledWith( + KDF_CONFIG, + kdfConfig, + mockUserId, + ); + }); + + it("throws error KDF cannot be null", async () => { + try { + await sutKdfConfigService.setKdfConfig(mockUserId, null as unknown as KdfConfig); + } catch (e) { + expect(e).toEqual(new Error("kdfConfig cannot be null")); + } + }); + + it("throws error userId cannot be null", async () => { + const kdfConfig: KdfConfig = new Argon2KdfConfig(3, 64, 4); + try { + await sutKdfConfigService.setKdfConfig(null as unknown as UserId, kdfConfig); + } catch (e) { + expect(e).toEqual(new Error("userId cannot be null")); + } + }); }); - it("setKdfConfig(): should set the Argon2KdfConfig config", async () => { - const kdfConfig: KdfConfig = new Argon2KdfConfig(2, 63, 3); - await sutKdfConfigService.setKdfConfig(mockUserId, kdfConfig); - expect(fakeStateProvider.mock.setUserState).toHaveBeenCalledWith( - KDF_CONFIG, - kdfConfig, - mockUserId, - ); + describe("getKdfConfig", () => { + it("throws error if userId is null", async () => { + await expect(sutKdfConfigService.getKdfConfig(null as unknown as UserId)).rejects.toThrow( + "userId cannot be null", + ); + }); + + it("throws if target user doesn't have a KkfConfig", async () => { + const errorMessage = "KdfConfig for user " + mockUserId + " is null"; + await expect(sutKdfConfigService.getKdfConfig(mockUserId)).rejects.toThrow(errorMessage); + }); + + it("returns KdfConfig of target user", async () => { + const kdfConfig: KdfConfig = new PBKDF2KdfConfig(500_000); + await fakeStateProvider.setUserState(KDF_CONFIG, kdfConfig, mockUserId); + await expect(sutKdfConfigService.getKdfConfig(mockUserId)).resolves.toEqual(kdfConfig); + }); }); - it("setKdfConfig(): should throw error KDF cannot be null", async () => { - try { - await sutKdfConfigService.setKdfConfig(mockUserId, null as unknown as KdfConfig); - } catch (e) { - expect(e).toEqual(new Error("kdfConfig cannot be null")); - } - }); + describe("getKdfConfig$", () => { + it("gets KdfConfig of provided user", async () => { + await expect( + firstValueFrom(sutKdfConfigService.getKdfConfig$(mockUserId)), + ).resolves.toBeNull(); + const kdfConfig: KdfConfig = new PBKDF2KdfConfig(500_000); + await fakeStateProvider.setUserState(KDF_CONFIG, kdfConfig, mockUserId); + await expect(firstValueFrom(sutKdfConfigService.getKdfConfig$(mockUserId))).resolves.toEqual( + kdfConfig, + ); + }); - it("setKdfConfig(): should throw error userId cannot be null", async () => { - const kdfConfig: KdfConfig = new Argon2KdfConfig(3, 64, 4); - try { - await sutKdfConfigService.setKdfConfig(null as unknown as UserId, kdfConfig); - } catch (e) { - expect(e).toEqual(new Error("userId cannot be null")); - } - }); + it("gets KdfConfig of provided user after changed", async () => { + await expect( + firstValueFrom(sutKdfConfigService.getKdfConfig$(mockUserId)), + ).resolves.toBeNull(); + await fakeStateProvider.setUserState(KDF_CONFIG, new PBKDF2KdfConfig(500_000), mockUserId); + const kdfConfigChanged: KdfConfig = new PBKDF2KdfConfig(500_001); + await fakeStateProvider.setUserState(KDF_CONFIG, kdfConfigChanged, mockUserId); + await expect(firstValueFrom(sutKdfConfigService.getKdfConfig$(mockUserId))).resolves.toEqual( + kdfConfigChanged, + ); + }); - it("getKdfConfig(): should get KdfConfig of active user", async () => { - const kdfConfig: KdfConfig = new PBKDF2KdfConfig(500_000); - await fakeStateProvider.setUserState(KDF_CONFIG, kdfConfig, mockUserId); - await expect(sutKdfConfigService.getKdfConfig()).resolves.toEqual(kdfConfig); - }); - - it("getKdfConfig(): should throw error KdfConfig can only be retrieved when there is active user", async () => { - fakeAccountService.activeAccountSubject.next(null); - try { - await sutKdfConfigService.getKdfConfig(); - } catch (e) { - expect(e).toEqual(new Error("KdfConfig can only be retrieved when there is active user")); - } - }); - - it("getKdfConfig(): should throw error KdfConfig for active user account state is null", async () => { - try { - await sutKdfConfigService.getKdfConfig(); - } catch (e) { - expect(e).toEqual(new Error("KdfConfig for active user account state is null")); - } - }); - - it("getKdfConfig$(UserId): should get KdfConfig of provided user", async () => { - await expect(firstValueFrom(sutKdfConfigService.getKdfConfig$(mockUserId))).resolves.toBeNull(); - const kdfConfig: KdfConfig = new PBKDF2KdfConfig(500_000); - await fakeStateProvider.setUserState(KDF_CONFIG, kdfConfig, mockUserId); - await expect(firstValueFrom(sutKdfConfigService.getKdfConfig$(mockUserId))).resolves.toEqual( - kdfConfig, - ); - }); - - it("getKdfConfig$(UserId): should get KdfConfig of provided user after changed", async () => { - await expect(firstValueFrom(sutKdfConfigService.getKdfConfig$(mockUserId))).resolves.toBeNull(); - await fakeStateProvider.setUserState(KDF_CONFIG, new PBKDF2KdfConfig(500_000), mockUserId); - const kdfConfigChanged: KdfConfig = new PBKDF2KdfConfig(500_001); - await fakeStateProvider.setUserState(KDF_CONFIG, kdfConfigChanged, mockUserId); - await expect(firstValueFrom(sutKdfConfigService.getKdfConfig$(mockUserId))).resolves.toEqual( - kdfConfigChanged, - ); - }); - - it("getKdfConfig$(UserId): should throw error userId cannot be null", async () => { - try { - sutKdfConfigService.getKdfConfig$(null as unknown as UserId); - } catch (e) { - expect(e).toEqual(new Error("userId cannot be null")); - } + it("throws error userId cannot be null", async () => { + try { + sutKdfConfigService.getKdfConfig$(null as unknown as UserId); + } catch (e) { + expect(e).toEqual(new Error("userId cannot be null")); + } + }); }); }); diff --git a/libs/key-management/src/kdf-config.service.ts b/libs/key-management/src/kdf-config.service.ts index efc5310e5a8..24635e87580 100644 --- a/libs/key-management/src/kdf-config.service.ts +++ b/libs/key-management/src/kdf-config.service.ts @@ -37,14 +37,14 @@ export class DefaultKdfConfigService implements KdfConfigService { await this.stateProvider.setUserState(KDF_CONFIG, kdfConfig, userId); } - async getKdfConfig(): Promise { - const userId = await firstValueFrom(this.stateProvider.activeUserId$); + async getKdfConfig(userId: UserId): Promise { if (userId == null) { - throw new Error("KdfConfig can only be retrieved when there is active user"); + throw new Error("userId cannot be null"); } + const state = await firstValueFrom(this.stateProvider.getUser(userId, KDF_CONFIG).state$); if (state == null) { - throw new Error("KdfConfig for active user account state is null"); + throw new Error("KdfConfig for user " + userId + " is null"); } return state; } diff --git a/libs/tools/export/vault-export/vault-export-core/src/services/base-vault-export.service.ts b/libs/tools/export/vault-export/vault-export-core/src/services/base-vault-export.service.ts index 0a92f4f02d7..c1526ba0f4b 100644 --- a/libs/tools/export/vault-export/vault-export-core/src/services/base-vault-export.service.ts +++ b/libs/tools/export/vault-export/vault-export-core/src/services/base-vault-export.service.ts @@ -4,6 +4,7 @@ import { PinServiceAbstraction } from "@bitwarden/auth/common"; import { CryptoFunctionService } from "@bitwarden/common/key-management/crypto/abstractions/crypto-function.service"; import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; +import { UserId } from "@bitwarden/common/types/guid"; import { CipherType } from "@bitwarden/common/vault/enums"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { KdfConfig, KdfConfigService, KdfType } from "@bitwarden/key-management"; @@ -17,8 +18,12 @@ export class BaseVaultExportService { private kdfConfigService: KdfConfigService, ) {} - protected async buildPasswordExport(clearText: string, password: string): Promise { - const kdfConfig: KdfConfig = await this.kdfConfigService.getKdfConfig(); + protected async buildPasswordExport( + userId: UserId, + clearText: string, + password: string, + ): Promise { + const kdfConfig: KdfConfig = await this.kdfConfigService.getKdfConfig(userId); const salt = Utils.fromBufferToB64(await this.cryptoFunctionService.randomBytes(16)); const key = await this.pinService.makePinKey(password, salt, kdfConfig); diff --git a/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.ts b/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.ts index d253ae8d0b1..96b19acd963 100644 --- a/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.ts +++ b/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.ts @@ -13,6 +13,7 @@ import { EncryptService } from "@bitwarden/common/key-management/crypto/abstract import { CipherWithIdExport, FolderWithIdExport } from "@bitwarden/common/models/export"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncArrayBuffer } from "@bitwarden/common/platform/models/domain/enc-array-buffer"; +import { UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; import { CipherType } from "@bitwarden/common/vault/enums"; @@ -59,19 +60,21 @@ export class IndividualVaultExportService * @param format The format of the export */ async getExport(format: ExportFormat = "csv"): Promise { + const userId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); if (format === "encrypted_json") { - return this.getEncryptedExport(); + return this.getEncryptedExport(userId); } else if (format === "zip") { - return this.getDecryptedExportZip(); + return this.getDecryptedExportZip(userId); } - return this.getDecryptedExport(format); + return this.getDecryptedExport(userId, format); } - /** Creates a password protected export of an individiual vault (My Vault) as a JSON file + /** Creates a password protected export of an individual vault (My Vault) as a JSON file * @param password The password to encrypt the export with * @returns A password-protected encrypted individual vault export */ async getPasswordProtectedExport(password: string): Promise { + const userId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); const exportVault = await this.getExport("json"); if (exportVault.type !== "text/plain") { @@ -80,19 +83,20 @@ export class IndividualVaultExportService return { type: "text/plain", - data: await this.buildPasswordExport(exportVault.data, password), + data: await this.buildPasswordExport(userId, exportVault.data, password), fileName: ExportHelper.getFileName("", "encrypted_json"), } as ExportedVaultAsString; } /** Creates a unencrypted export of an individual vault including attachments + * @param activeUserId The user ID of the user requesting the export * @returns A unencrypted export including attachments */ - async getDecryptedExportZip(): Promise { + async getDecryptedExportZip(activeUserId: UserId): Promise { const zip = new JSZip(); // ciphers - const exportedVault = await this.getDecryptedExport("json"); + const exportedVault = await this.getDecryptedExport(activeUserId, "json"); zip.file("data.json", exportedVault.data); const attachmentsFolder = zip.folder("attachments"); @@ -100,8 +104,6 @@ export class IndividualVaultExportService throw new Error("Error creating attachments folder"); } - const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); - // attachments for (const cipher of await this.cipherService.getAllDecrypted(activeUserId)) { if ( @@ -161,11 +163,13 @@ export class IndividualVaultExportService } } - private async getDecryptedExport(format: "json" | "csv"): Promise { + private async getDecryptedExport( + activeUserId: UserId, + format: "json" | "csv", + ): Promise { let decFolders: FolderView[] = []; let decCiphers: CipherView[] = []; const promises = []; - const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); promises.push( firstValueFrom(this.folderService.folderViews$(activeUserId)).then((folders) => { @@ -196,11 +200,10 @@ export class IndividualVaultExportService } as ExportedVaultAsString; } - private async getEncryptedExport(): Promise { + private async getEncryptedExport(activeUserId: UserId): Promise { let folders: Folder[] = []; let ciphers: Cipher[] = []; const promises = []; - const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); promises.push( firstValueFrom(this.folderService.folders$(activeUserId)).then((f) => { @@ -216,9 +219,7 @@ export class IndividualVaultExportService await Promise.all(promises); - const userKey = await this.keyService.getUserKeyWithLegacySupport( - await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)), - ); + const userKey = await this.keyService.getUserKeyWithLegacySupport(activeUserId); const encKeyValidation = await this.encryptService.encrypt(Utils.newGuid(), userKey); const jsonDoc: BitwardenEncryptedIndividualJsonExport = { diff --git a/libs/tools/export/vault-export/vault-export-core/src/services/org-vault-export.service.ts b/libs/tools/export/vault-export/vault-export-core/src/services/org-vault-export.service.ts index e4ed105d1ad..86edf67bf03 100644 --- a/libs/tools/export/vault-export/vault-export-core/src/services/org-vault-export.service.ts +++ b/libs/tools/export/vault-export/vault-export-core/src/services/org-vault-export.service.ts @@ -18,7 +18,7 @@ import { CryptoFunctionService } from "@bitwarden/common/key-management/crypto/a import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { CipherWithIdExport, CollectionWithIdExport } from "@bitwarden/common/models/export"; import { Utils } from "@bitwarden/common/platform/misc/utils"; -import { OrganizationId } from "@bitwarden/common/types/guid"; +import { OrganizationId, UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CipherType } from "@bitwarden/common/vault/enums"; import { CipherData } from "@bitwarden/common/vault/models/data/cipher.data"; @@ -67,6 +67,7 @@ export class OrganizationVaultExportService password: string, onlyManagedCollections: boolean, ): Promise { + const userId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); const exportVault = await this.getOrganizationExport( organizationId, "json", @@ -75,7 +76,7 @@ export class OrganizationVaultExportService return { type: "text/plain", - data: await this.buildPasswordExport(exportVault.data, password), + data: await this.buildPasswordExport(userId, exportVault.data, password), fileName: ExportHelper.getFileName("org", "encrypted_json"), } as ExportedVaultAsString; } @@ -102,12 +103,13 @@ export class OrganizationVaultExportService if (format === "zip") { throw new Error("Zip export not supported for organization"); } + const userId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); if (format === "encrypted_json") { return { type: "text/plain", data: onlyManagedCollections - ? await this.getEncryptedManagedExport(organizationId) + ? await this.getEncryptedManagedExport(userId, organizationId) : await this.getOrganizationEncryptedExport(organizationId), fileName: ExportHelper.getFileName("org", "encrypted_json"), } as ExportedVaultAsString; @@ -116,20 +118,20 @@ export class OrganizationVaultExportService return { type: "text/plain", data: onlyManagedCollections - ? await this.getDecryptedManagedExport(organizationId, format) - : await this.getOrganizationDecryptedExport(organizationId, format), + ? await this.getDecryptedManagedExport(userId, organizationId, format) + : await this.getOrganizationDecryptedExport(userId, organizationId, format), fileName: ExportHelper.getFileName("org", format), } as ExportedVaultAsString; } private async getOrganizationDecryptedExport( + activeUserId: UserId, organizationId: string, format: "json" | "csv", ): Promise { const decCollections: CollectionView[] = []; const decCiphers: CipherView[] = []; const promises = []; - const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); promises.push( this.apiService.getOrganizationExport(organizationId).then((exportData) => { @@ -210,6 +212,7 @@ export class OrganizationVaultExportService } private async getDecryptedManagedExport( + activeUserId: UserId, organizationId: string, format: "json" | "csv", ): Promise { @@ -217,7 +220,6 @@ export class OrganizationVaultExportService let allDecCiphers: CipherView[] = []; let decCollections: CollectionView[] = []; const promises = []; - const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); promises.push( this.collectionService.getAllDecrypted().then(async (collections) => { @@ -245,12 +247,14 @@ export class OrganizationVaultExportService return this.buildJsonExport(decCollections, decCiphers); } - private async getEncryptedManagedExport(organizationId: string): Promise { + private async getEncryptedManagedExport( + activeUserId: UserId, + organizationId: string, + ): Promise { let encCiphers: Cipher[] = []; let allCiphers: Cipher[] = []; let encCollections: Collection[] = []; const promises = []; - const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); promises.push( this.collectionService.getAll().then((collections) => { From a92afe1efb9ca5dadb027cf1849a37b6a7716c67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rui=20Tom=C3=A9?= <108268980+r-tome@users.noreply.github.com> Date: Wed, 30 Apr 2025 11:40:55 +0100 Subject: [PATCH 03/19] [PM-17690] Improve collection search to consider nested collections (#14420) * Add getFlatCollectionTree function and corresponding tests - Implemented getFlatCollectionTree to flatten a tree structure of collections. - Added unit tests for getFlatCollectionTree to verify functionality. * Refactor VaultComponent to utilize getFlatCollectionTree to search within all sub-levels - Updated vault.component.ts to import and use getFlatCollectionTree for flattening collection nodes during search. - Ensured consistent handling of collections across both vault and admin-console components. --- .../utils/collection-utils.spec.ts | 62 ++++++++++++++++++- .../collections/utils/collection-utils.ts | 21 +++++++ .../collections/vault.component.ts | 24 ++++--- .../vault/individual-vault/vault.component.ts | 27 +++++--- 4 files changed, 116 insertions(+), 18 deletions(-) diff --git a/apps/web/src/app/admin-console/organizations/collections/utils/collection-utils.spec.ts b/apps/web/src/app/admin-console/organizations/collections/utils/collection-utils.spec.ts index 0354a08c285..abd99d37355 100644 --- a/apps/web/src/app/admin-console/organizations/collections/utils/collection-utils.spec.ts +++ b/apps/web/src/app/admin-console/organizations/collections/utils/collection-utils.spec.ts @@ -1,6 +1,7 @@ import { CollectionView } from "@bitwarden/admin-console/common"; +import { TreeNode } from "@bitwarden/common/vault/models/domain/tree-node"; -import { getNestedCollectionTree } from "./collection-utils"; +import { getNestedCollectionTree, getFlatCollectionTree } from "./collection-utils"; describe("CollectionUtils Service", () => { describe("getNestedCollectionTree", () => { @@ -36,4 +37,63 @@ describe("CollectionUtils Service", () => { expect(result).toEqual([]); }); }); + + describe("getFlatCollectionTree", () => { + it("should flatten a tree node with no children", () => { + // Arrange + const collection = new CollectionView(); + collection.name = "Test Collection"; + collection.id = "test-id"; + + const treeNodes: TreeNode[] = [ + new TreeNode(collection, null), + ]; + + // Act + const result = getFlatCollectionTree(treeNodes); + + // Assert + expect(result.length).toBe(1); + expect(result[0]).toBe(collection); + }); + + it("should flatten a tree node with children", () => { + // Arrange + const parentCollection = new CollectionView(); + parentCollection.name = "Parent"; + parentCollection.id = "parent-id"; + + const child1Collection = new CollectionView(); + child1Collection.name = "Child 1"; + child1Collection.id = "child1-id"; + + const child2Collection = new CollectionView(); + child2Collection.name = "Child 2"; + child2Collection.id = "child2-id"; + + const grandchildCollection = new CollectionView(); + grandchildCollection.name = "Grandchild"; + grandchildCollection.id = "grandchild-id"; + + const parentNode = new TreeNode(parentCollection, null); + const child1Node = new TreeNode(child1Collection, parentNode); + const child2Node = new TreeNode(child2Collection, parentNode); + const grandchildNode = new TreeNode(grandchildCollection, child1Node); + + parentNode.children = [child1Node, child2Node]; + child1Node.children = [grandchildNode]; + + const treeNodes: TreeNode[] = [parentNode]; + + // Act + const result = getFlatCollectionTree(treeNodes); + + // Assert + expect(result.length).toBe(4); + expect(result[0]).toBe(parentCollection); + expect(result).toContain(child1Collection); + expect(result).toContain(child2Collection); + expect(result).toContain(grandchildCollection); + }); + }); }); diff --git a/apps/web/src/app/admin-console/organizations/collections/utils/collection-utils.ts b/apps/web/src/app/admin-console/organizations/collections/utils/collection-utils.ts index 2926ff3acee..95ae911bbf6 100644 --- a/apps/web/src/app/admin-console/organizations/collections/utils/collection-utils.ts +++ b/apps/web/src/app/admin-console/organizations/collections/utils/collection-utils.ts @@ -37,6 +37,27 @@ export function getNestedCollectionTree( return nodes; } +export function getFlatCollectionTree( + nodes: TreeNode[], +): CollectionAdminView[]; +export function getFlatCollectionTree(nodes: TreeNode[]): CollectionView[]; +export function getFlatCollectionTree( + nodes: TreeNode[], +): (CollectionView | CollectionAdminView)[] { + if (!nodes || nodes.length === 0) { + return []; + } + + return nodes.flatMap((node) => { + if (!node.children || node.children.length === 0) { + return [node.node]; + } + + const children = getFlatCollectionTree(node.children); + return [node.node, ...children]; + }); +} + function cloneCollection(collection: CollectionView): CollectionView; function cloneCollection(collection: CollectionAdminView): CollectionAdminView; function cloneCollection( diff --git a/apps/web/src/app/admin-console/organizations/collections/vault.component.ts b/apps/web/src/app/admin-console/organizations/collections/vault.component.ts index ccb97e2a703..7d159da917c 100644 --- a/apps/web/src/app/admin-console/organizations/collections/vault.component.ts +++ b/apps/web/src/app/admin-console/organizations/collections/vault.component.ts @@ -121,7 +121,7 @@ import { BulkCollectionsDialogResult, } from "./bulk-collections-dialog"; import { CollectionAccessRestrictedComponent } from "./collection-access-restricted.component"; -import { getNestedCollectionTree } from "./utils"; +import { getNestedCollectionTree, getFlatCollectionTree } from "./utils"; import { VaultFilterModule } from "./vault-filter/vault-filter.module"; import { VaultHeaderComponent } from "./vault-header/vault-header.component"; @@ -432,23 +432,33 @@ export class VaultComponent implements OnInit, OnDestroy { } this.showAddAccessToggle = false; - let collectionsToReturn = []; + let searchableCollectionNodes: TreeNode[] = []; if (filter.collectionId === undefined || filter.collectionId === All) { - collectionsToReturn = collections.map((c) => c.node); + searchableCollectionNodes = collections; } else { const selectedCollection = ServiceUtils.getTreeNodeObjectFromList( collections, filter.collectionId, ); - collectionsToReturn = selectedCollection?.children.map((c) => c.node) ?? []; + searchableCollectionNodes = selectedCollection?.children ?? []; } + let collectionsToReturn: CollectionAdminView[] = []; + if (await this.searchService.isSearchable(this.userId, searchText)) { + // Flatten the tree for searching through all levels + const flatCollectionTree: CollectionAdminView[] = + getFlatCollectionTree(searchableCollectionNodes); + collectionsToReturn = this.searchPipe.transform( - collectionsToReturn, + flatCollectionTree, searchText, - (collection: CollectionAdminView) => collection.name, - (collection: CollectionAdminView) => collection.id, + (collection) => collection.name, + (collection) => collection.id, + ); + } else { + collectionsToReturn = searchableCollectionNodes.map( + (treeNode: TreeNode): CollectionAdminView => treeNode.node, ); } diff --git a/apps/web/src/app/vault/individual-vault/vault.component.ts b/apps/web/src/app/vault/individual-vault/vault.component.ts index 67bd6a6a526..55bbd0c0651 100644 --- a/apps/web/src/app/vault/individual-vault/vault.component.ts +++ b/apps/web/src/app/vault/individual-vault/vault.component.ts @@ -79,7 +79,10 @@ import { PasswordRepromptService, } from "@bitwarden/vault"; -import { getNestedCollectionTree } from "../../admin-console/organizations/collections"; +import { + getNestedCollectionTree, + getFlatCollectionTree, +} from "../../admin-console/organizations/collections"; import { CollectionDialogAction, CollectionDialogTabType, @@ -372,31 +375,35 @@ export class VaultComponent implements OnInit, OnDestroy { if (filter.collectionId === undefined || filter.collectionId === Unassigned) { return []; } - let collectionsToReturn = []; + let searchableCollectionNodes: TreeNode[] = []; if (filter.organizationId !== undefined && filter.collectionId === All) { - collectionsToReturn = collections - .filter((c) => c.node.organizationId === filter.organizationId) - .map((c) => c.node); + searchableCollectionNodes = collections.filter( + (c) => c.node.organizationId === filter.organizationId, + ); } else if (filter.collectionId === All) { - collectionsToReturn = collections.map((c) => c.node); + searchableCollectionNodes = collections; } else { const selectedCollection = ServiceUtils.getTreeNodeObjectFromList( collections, filter.collectionId, ); - collectionsToReturn = selectedCollection?.children.map((c) => c.node) ?? []; + searchableCollectionNodes = selectedCollection?.children ?? []; } if (await this.searchService.isSearchable(activeUserId, searchText)) { - collectionsToReturn = this.searchPipe.transform( - collectionsToReturn, + // Flatten the tree for searching through all levels + const flatCollectionTree: CollectionView[] = + getFlatCollectionTree(searchableCollectionNodes); + + return this.searchPipe.transform( + flatCollectionTree, searchText, (collection) => collection.name, (collection) => collection.id, ); } - return collectionsToReturn; + return searchableCollectionNodes.map((treeNode: TreeNode) => treeNode.node); }), shareReplay({ refCount: true, bufferSize: 1 }), ); From 67b0a19319a5c7d39560e8ee794a5e5ab356e59c Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Wed, 30 Apr 2025 15:36:48 +0200 Subject: [PATCH 04/19] [PM-21001] Move tools usage of encrypt service (#14540) * Add new encrypt service functions * Undo changes * Cleanup * Fix build * Fix comments * Move tools usage of encrypt service --- .../services/critical-apps.service.spec.ts | 12 ++++++------ .../services/critical-apps.service.ts | 6 +++--- .../organization-key-encryptor.spec.ts | 10 ++++++---- .../cryptography/organization-key-encryptor.ts | 4 ++-- .../cryptography/user-key-encryptor.spec.ts | 10 ++++++---- .../src/tools/cryptography/user-key-encryptor.ts | 4 ++-- .../src/tools/send/models/domain/send.spec.ts | 2 +- libs/common/src/tools/send/models/domain/send.ts | 3 ++- .../src/tools/send/services/send.service.spec.ts | 4 +++- .../src/tools/send/services/send.service.ts | 16 +++++++--------- .../bitwarden/bitwarden-json-importer.ts | 2 +- ...bitwarden-password-protected-importer.spec.ts | 2 +- .../bitwarden-password-protected-importer.ts | 4 ++-- .../src/services/base-vault-export.service.ts | 4 ++-- .../individual-vault-export.service.spec.ts | 12 ++++++------ .../services/individual-vault-export.service.ts | 4 ++-- .../src/services/org-vault-export.service.ts | 2 +- .../src/services/vault-export.service.spec.ts | 6 +++--- .../src/legacy-password-history-decryptor.ts | 2 +- .../src/local-generator-history.service.spec.ts | 6 ++++-- 20 files changed, 61 insertions(+), 54 deletions(-) diff --git a/bitwarden_license/bit-common/src/tools/reports/risk-insights/services/critical-apps.service.spec.ts b/bitwarden_license/bit-common/src/tools/reports/risk-insights/services/critical-apps.service.spec.ts index d2d48edf869..b3e8e11f4f7 100644 --- a/bitwarden_license/bit-common/src/tools/reports/risk-insights/services/critical-apps.service.spec.ts +++ b/bitwarden_license/bit-common/src/tools/reports/risk-insights/services/critical-apps.service.spec.ts @@ -59,7 +59,7 @@ describe("CriticalAppsService", () => { { id: "id2", organizationId: "org1", uri: "https://example.org" }, ] as PasswordHealthReportApplicationsResponse[]; - encryptService.encrypt.mockResolvedValue(new EncString("encryptedUrlName")); + encryptService.encryptString.mockResolvedValue(new EncString("encryptedUrlName")); criticalAppsApiService.saveCriticalApps.mockReturnValue(of(response)); // act @@ -67,7 +67,7 @@ describe("CriticalAppsService", () => { // expectations expect(keyService.getOrgKey).toHaveBeenCalledWith("org1"); - expect(encryptService.encrypt).toHaveBeenCalledTimes(2); + expect(encryptService.encryptString).toHaveBeenCalledTimes(2); expect(criticalAppsApiService.saveCriticalApps).toHaveBeenCalledWith(request); }); @@ -95,7 +95,7 @@ describe("CriticalAppsService", () => { { id: "id1", organizationId: "org1", uri: "test" }, ] as PasswordHealthReportApplicationsResponse[]; - encryptService.encrypt.mockResolvedValue(new EncString("encryptedUrlName")); + encryptService.encryptString.mockResolvedValue(new EncString("encryptedUrlName")); criticalAppsApiService.saveCriticalApps.mockReturnValue(of(response)); // act @@ -103,7 +103,7 @@ describe("CriticalAppsService", () => { // expectations expect(keyService.getOrgKey).toHaveBeenCalledWith("org1"); - expect(encryptService.encrypt).toHaveBeenCalledTimes(1); + expect(encryptService.encryptString).toHaveBeenCalledTimes(1); expect(criticalAppsApiService.saveCriticalApps).toHaveBeenCalledWith(request); }); @@ -114,7 +114,7 @@ describe("CriticalAppsService", () => { { id: "id2", organizationId: "org1", uri: "https://example.org" }, ] as PasswordHealthReportApplicationsResponse[]; - encryptService.decryptToUtf8.mockResolvedValue("https://example.com"); + encryptService.decryptString.mockResolvedValue("https://example.com"); criticalAppsApiService.getCriticalApps.mockReturnValue(of(response)); const mockRandomBytes = new Uint8Array(64) as CsprngArray; @@ -125,7 +125,7 @@ describe("CriticalAppsService", () => { flush(); expect(keyService.getOrgKey).toHaveBeenCalledWith(orgId.toString()); - expect(encryptService.decryptToUtf8).toHaveBeenCalledTimes(2); + expect(encryptService.decryptString).toHaveBeenCalledTimes(2); expect(criticalAppsApiService.getCriticalApps).toHaveBeenCalledWith(orgId); })); diff --git a/bitwarden_license/bit-common/src/tools/reports/risk-insights/services/critical-apps.service.ts b/bitwarden_license/bit-common/src/tools/reports/risk-insights/services/critical-apps.service.ts index bc8edc17360..b879ef94705 100644 --- a/bitwarden_license/bit-common/src/tools/reports/risk-insights/services/critical-apps.service.ts +++ b/bitwarden_license/bit-common/src/tools/reports/risk-insights/services/critical-apps.service.ts @@ -81,7 +81,7 @@ export class CriticalAppsService { // add the new entries to the criticalAppsList const updatedList = [...this.criticalAppsList.value]; for (const responseItem of dbResponse) { - const decryptedUrl = await this.encryptService.decryptToUtf8( + const decryptedUrl = await this.encryptService.decryptString( new EncString(responseItem.uri), key, ); @@ -138,7 +138,7 @@ export class CriticalAppsService { const results = response.map(async (r: PasswordHealthReportApplicationsResponse) => { const encrypted = new EncString(r.uri); - const uri = await this.encryptService.decryptToUtf8(encrypted, key); + const uri = await this.encryptService.decryptString(encrypted, key); return { id: r.id, organizationId: r.organizationId, uri: uri }; }); return forkJoin(results); @@ -164,7 +164,7 @@ export class CriticalAppsService { newEntries: string[], ): Promise { const criticalAppsPromises = newEntries.map(async (url) => { - const encryptedUrlName = await this.encryptService.encrypt(url, key); + const encryptedUrlName = await this.encryptService.encryptString(url, key); return { organizationId: orgId, url: encryptedUrlName?.encryptedString?.toString() ?? "", diff --git a/libs/common/src/tools/cryptography/organization-key-encryptor.spec.ts b/libs/common/src/tools/cryptography/organization-key-encryptor.spec.ts index 3d93db81389..9f03d618cdc 100644 --- a/libs/common/src/tools/cryptography/organization-key-encryptor.spec.ts +++ b/libs/common/src/tools/cryptography/organization-key-encryptor.spec.ts @@ -22,8 +22,10 @@ describe("OrgKeyEncryptor", () => { // on this property--that the facade treats its data like a opaque objects--to trace // the data through several function calls. Should the encryptor interact with the // objects themselves, these mocks will break. - encryptService.encrypt.mockImplementation((p) => Promise.resolve(p as unknown as EncString)); - encryptService.decryptToUtf8.mockImplementation((c) => Promise.resolve(c as unknown as string)); + encryptService.encryptString.mockImplementation((p) => + Promise.resolve(p as unknown as EncString), + ); + encryptService.decryptString.mockImplementation((c) => Promise.resolve(c as unknown as string)); dataPacker.pack.mockImplementation((v) => v as string); dataPacker.unpack.mockImplementation((v: string) => v as T); }); @@ -95,7 +97,7 @@ describe("OrgKeyEncryptor", () => { // these are data flow expectations; the operations all all pass-through mocks expect(dataPacker.pack).toHaveBeenCalledWith(value); - expect(encryptService.encrypt).toHaveBeenCalledWith(value, orgKey); + expect(encryptService.encryptString).toHaveBeenCalledWith(value, orgKey); expect(result).toBe(value); }); }); @@ -117,7 +119,7 @@ describe("OrgKeyEncryptor", () => { const result = await encryptor.decrypt(secret); // these are data flow expectations; the operations all all pass-through mocks - expect(encryptService.decryptToUtf8).toHaveBeenCalledWith(secret, orgKey); + expect(encryptService.decryptString).toHaveBeenCalledWith(secret, orgKey); expect(dataPacker.unpack).toHaveBeenCalledWith(secret); expect(result).toBe(secret); }); diff --git a/libs/common/src/tools/cryptography/organization-key-encryptor.ts b/libs/common/src/tools/cryptography/organization-key-encryptor.ts index 31f3db91232..99b47c48670 100644 --- a/libs/common/src/tools/cryptography/organization-key-encryptor.ts +++ b/libs/common/src/tools/cryptography/organization-key-encryptor.ts @@ -37,7 +37,7 @@ export class OrganizationKeyEncryptor extends OrganizationEncryptor { this.assertHasValue("secret", secret); let packed = this.dataPacker.pack(secret); - const encrypted = await this.encryptService.encrypt(packed, this.key); + const encrypted = await this.encryptService.encryptString(packed, this.key); packed = null; return encrypted; @@ -46,7 +46,7 @@ export class OrganizationKeyEncryptor extends OrganizationEncryptor { async decrypt(secret: EncString): Promise> { this.assertHasValue("secret", secret); - let decrypted = await this.encryptService.decryptToUtf8(secret, this.key); + let decrypted = await this.encryptService.decryptString(secret, this.key); const unpacked = this.dataPacker.unpack(decrypted); decrypted = null; diff --git a/libs/common/src/tools/cryptography/user-key-encryptor.spec.ts b/libs/common/src/tools/cryptography/user-key-encryptor.spec.ts index e52190500b0..5bcb57ec563 100644 --- a/libs/common/src/tools/cryptography/user-key-encryptor.spec.ts +++ b/libs/common/src/tools/cryptography/user-key-encryptor.spec.ts @@ -22,8 +22,10 @@ describe("UserKeyEncryptor", () => { // on this property--that the facade treats its data like a opaque objects--to trace // the data through several function calls. Should the encryptor interact with the // objects themselves, these mocks will break. - encryptService.encrypt.mockImplementation((p) => Promise.resolve(p as unknown as EncString)); - encryptService.decryptToUtf8.mockImplementation((c) => Promise.resolve(c as unknown as string)); + encryptService.encryptString.mockImplementation((p) => + Promise.resolve(p as unknown as EncString), + ); + encryptService.decryptString.mockImplementation((c) => Promise.resolve(c as unknown as string)); dataPacker.pack.mockImplementation((v) => v as string); dataPacker.unpack.mockImplementation((v: string) => v as T); }); @@ -95,7 +97,7 @@ describe("UserKeyEncryptor", () => { // these are data flow expectations; the operations all all pass-through mocks expect(dataPacker.pack).toHaveBeenCalledWith(value); - expect(encryptService.encrypt).toHaveBeenCalledWith(value, userKey); + expect(encryptService.encryptString).toHaveBeenCalledWith(value, userKey); expect(result).toBe(value); }); }); @@ -117,7 +119,7 @@ describe("UserKeyEncryptor", () => { const result = await encryptor.decrypt(secret); // these are data flow expectations; the operations all all pass-through mocks - expect(encryptService.decryptToUtf8).toHaveBeenCalledWith(secret, userKey); + expect(encryptService.decryptString).toHaveBeenCalledWith(secret, userKey); expect(dataPacker.unpack).toHaveBeenCalledWith(secret); expect(result).toBe(secret); }); diff --git a/libs/common/src/tools/cryptography/user-key-encryptor.ts b/libs/common/src/tools/cryptography/user-key-encryptor.ts index 4b7cd1516a0..74e41f7af6d 100644 --- a/libs/common/src/tools/cryptography/user-key-encryptor.ts +++ b/libs/common/src/tools/cryptography/user-key-encryptor.ts @@ -37,7 +37,7 @@ export class UserKeyEncryptor extends UserEncryptor { this.assertHasValue("secret", secret); let packed = this.dataPacker.pack(secret); - const encrypted = await this.encryptService.encrypt(packed, this.key); + const encrypted = await this.encryptService.encryptString(packed, this.key); packed = null; return encrypted; @@ -46,7 +46,7 @@ export class UserKeyEncryptor extends UserEncryptor { async decrypt(secret: EncString): Promise> { this.assertHasValue("secret", secret); - let decrypted = await this.encryptService.decryptToUtf8(secret, this.key); + let decrypted = await this.encryptService.decryptString(secret, this.key); const unpacked = this.dataPacker.unpack(decrypted); decrypted = null; diff --git a/libs/common/src/tools/send/models/domain/send.spec.ts b/libs/common/src/tools/send/models/domain/send.spec.ts index 79f6c03adc8..7112ad7f751 100644 --- a/libs/common/src/tools/send/models/domain/send.spec.ts +++ b/libs/common/src/tools/send/models/domain/send.spec.ts @@ -112,7 +112,7 @@ describe("Send", () => { const encryptService = mock(); const keyService = mock(); - encryptService.decryptToBytes + encryptService.decryptBytes .calledWith(send.key, userKey) .mockResolvedValue(makeStaticByteArray(32)); keyService.makeSendKey.mockResolvedValue("cryptoKey" as any); diff --git a/libs/common/src/tools/send/models/domain/send.ts b/libs/common/src/tools/send/models/domain/send.ts index f12a0010fab..78d7966bb63 100644 --- a/libs/common/src/tools/send/models/domain/send.ts +++ b/libs/common/src/tools/send/models/domain/send.ts @@ -79,7 +79,8 @@ export class Send extends Domain { try { const sendKeyEncryptionKey = await keyService.getUserKey(); - model.key = await encryptService.decryptToBytes(this.key, sendKeyEncryptionKey); + // model.key is a seed used to derive a key, not a SymmetricCryptoKey + model.key = await encryptService.decryptBytes(this.key, sendKeyEncryptionKey); model.cryptoKey = await keyService.makeSendKey(model.key); // FIXME: Remove when updating file. Eslint update // eslint-disable-next-line @typescript-eslint/no-unused-vars diff --git a/libs/common/src/tools/send/services/send.service.spec.ts b/libs/common/src/tools/send/services/send.service.spec.ts index cd8d52fe373..65fd53edd75 100644 --- a/libs/common/src/tools/send/services/send.service.spec.ts +++ b/libs/common/src/tools/send/services/send.service.spec.ts @@ -477,7 +477,9 @@ describe("SendService", () => { let encryptedKey: EncString; beforeEach(() => { - encryptService.decryptToBytes.mockResolvedValue(new Uint8Array(32)); + encryptService.unwrapSymmetricKey.mockResolvedValue( + new SymmetricCryptoKey(new Uint8Array(32)), + ); encryptedKey = new EncString("Re-encrypted Send Key"); encryptService.wrapSymmetricKey.mockResolvedValue(encryptedKey); }); diff --git a/libs/common/src/tools/send/services/send.service.ts b/libs/common/src/tools/send/services/send.service.ts index cefd9942d29..db3834789c8 100644 --- a/libs/common/src/tools/send/services/send.service.ts +++ b/libs/common/src/tools/send/services/send.service.ts @@ -86,12 +86,12 @@ export class SendService implements InternalSendServiceAbstraction { userKey = await this.keyService.getUserKey(); } // Key is not a SymmetricCryptoKey, but key material used to derive the cryptoKey - send.key = await this.encryptService.encrypt(model.key, userKey); - send.name = await this.encryptService.encrypt(model.name, model.cryptoKey); - send.notes = await this.encryptService.encrypt(model.notes, model.cryptoKey); + send.key = await this.encryptService.encryptBytes(model.key, userKey); + send.name = await this.encryptService.encryptString(model.name, model.cryptoKey); + send.notes = await this.encryptService.encryptString(model.notes, model.cryptoKey); if (send.type === SendType.Text) { send.text = new SendText(); - send.text.text = await this.encryptService.encrypt(model.text.text, model.cryptoKey); + send.text.text = await this.encryptService.encryptString(model.text.text, model.cryptoKey); send.text.hidden = model.text.hidden; } else if (send.type === SendType.File) { send.file = new SendFile(); @@ -292,9 +292,7 @@ export class SendService implements InternalSendServiceAbstraction { ) { const requests = await Promise.all( sends.map(async (send) => { - const sendKey = new SymmetricCryptoKey( - await this.encryptService.decryptToBytes(send.key, originalUserKey), - ); + const sendKey = await this.encryptService.unwrapSymmetricKey(send.key, originalUserKey); send.key = await this.encryptService.wrapSymmetricKey(sendKey, rotateUserKey); return new SendWithIdRequest(send); }), @@ -333,8 +331,8 @@ export class SendService implements InternalSendServiceAbstraction { if (key == null) { key = await this.keyService.getUserKey(); } - const encFileName = await this.encryptService.encrypt(fileName, key); - const encFileData = await this.encryptService.encryptToBytes(new Uint8Array(data), key); + const encFileName = await this.encryptService.encryptString(fileName, key); + const encFileData = await this.encryptService.encryptFileData(new Uint8Array(data), key); return [encFileName, encFileData]; } diff --git a/libs/importer/src/importers/bitwarden/bitwarden-json-importer.ts b/libs/importer/src/importers/bitwarden/bitwarden-json-importer.ts index f01e6571439..9284718a063 100644 --- a/libs/importer/src/importers/bitwarden/bitwarden-json-importer.ts +++ b/libs/importer/src/importers/bitwarden/bitwarden-json-importer.ts @@ -72,7 +72,7 @@ export class BitwardenJsonImporter extends BaseImporter implements Importer { keyForDecryption = await this.keyService.getUserKeyWithLegacySupport(); } const encKeyValidation = new EncString(results.encKeyValidation_DO_NOT_EDIT); - const encKeyValidationDecrypt = await this.encryptService.decryptToUtf8( + const encKeyValidationDecrypt = await this.encryptService.decryptString( encKeyValidation, keyForDecryption, ); diff --git a/libs/importer/src/importers/bitwarden/bitwarden-password-protected-importer.spec.ts b/libs/importer/src/importers/bitwarden/bitwarden-password-protected-importer.spec.ts index 66deabf0634..8d0f5dfcc1c 100644 --- a/libs/importer/src/importers/bitwarden/bitwarden-password-protected-importer.spec.ts +++ b/libs/importer/src/importers/bitwarden/bitwarden-password-protected-importer.spec.ts @@ -92,7 +92,7 @@ describe("BitwardenPasswordProtectedImporter", () => { }); it("succeeds with default jdoc", async () => { - encryptService.decryptToUtf8.mockReturnValue(Promise.resolve(emptyUnencryptedExport)); + encryptService.decryptString.mockReturnValue(Promise.resolve(emptyUnencryptedExport)); expect((await importer.parse(JSON.stringify(jDoc))).success).toEqual(true); }); diff --git a/libs/importer/src/importers/bitwarden/bitwarden-password-protected-importer.ts b/libs/importer/src/importers/bitwarden/bitwarden-password-protected-importer.ts index 02a417c2169..878f9cf5819 100644 --- a/libs/importer/src/importers/bitwarden/bitwarden-password-protected-importer.ts +++ b/libs/importer/src/importers/bitwarden/bitwarden-password-protected-importer.ts @@ -69,7 +69,7 @@ export class BitwardenPasswordProtectedImporter extends BitwardenJsonImporter im } const encData = new EncString(parsedData.data); - const clearTextData = await this.encryptService.decryptToUtf8(encData, this.key); + const clearTextData = await this.encryptService.decryptString(encData, this.key); return await super.parse(clearTextData); } @@ -90,7 +90,7 @@ export class BitwardenPasswordProtectedImporter extends BitwardenJsonImporter im const encKeyValidation = new EncString(jdoc.encKeyValidation_DO_NOT_EDIT); - const encKeyValidationDecrypt = await this.encryptService.decryptToUtf8( + const encKeyValidationDecrypt = await this.encryptService.decryptString( encKeyValidation, this.key, ); diff --git a/libs/tools/export/vault-export/vault-export-core/src/services/base-vault-export.service.ts b/libs/tools/export/vault-export/vault-export-core/src/services/base-vault-export.service.ts index c1526ba0f4b..9a64298ffba 100644 --- a/libs/tools/export/vault-export/vault-export-core/src/services/base-vault-export.service.ts +++ b/libs/tools/export/vault-export/vault-export-core/src/services/base-vault-export.service.ts @@ -28,8 +28,8 @@ export class BaseVaultExportService { const salt = Utils.fromBufferToB64(await this.cryptoFunctionService.randomBytes(16)); const key = await this.pinService.makePinKey(password, salt, kdfConfig); - const encKeyValidation = await this.encryptService.encrypt(Utils.newGuid(), key); - const encText = await this.encryptService.encrypt(clearText, key); + const encKeyValidation = await this.encryptService.encryptString(Utils.newGuid(), key); + const encText = await this.encryptService.encryptString(clearText, key); const jsonDoc: BitwardenPasswordProtectedFileFormat = { encrypted: true, diff --git a/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.spec.ts b/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.spec.ts index 15791ae04fb..ae408af421b 100644 --- a/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.spec.ts +++ b/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.spec.ts @@ -209,7 +209,7 @@ describe("VaultExportService", () => { folderService.folderViews$.mockReturnValue(of(UserFolderViews)); folderService.folders$.mockReturnValue(of(UserFolders)); kdfConfigService.getKdfConfig.mockResolvedValue(DEFAULT_KDF_CONFIG); - encryptService.encrypt.mockResolvedValue(new EncString("encrypted")); + encryptService.encryptString.mockResolvedValue(new EncString("encrypted")); apiService.getAttachmentData.mockResolvedValue(attachmentResponse); exportService = new IndividualVaultExportService( @@ -313,7 +313,7 @@ describe("VaultExportService", () => { cipherService.getAllDecrypted.mockResolvedValue([cipherView]); folderService.getAllDecryptedFromState.mockResolvedValue([]); - encryptService.decryptToBytes.mockResolvedValue(new Uint8Array(255)); + encryptService.decryptFileData.mockResolvedValue(new Uint8Array(255)); global.fetch = jest.fn(() => Promise.resolve({ @@ -338,7 +338,7 @@ describe("VaultExportService", () => { cipherService.getAllDecrypted.mockResolvedValue([cipherView]); folderService.getAllDecryptedFromState.mockResolvedValue([]); - encryptService.decryptToBytes.mockResolvedValue(new Uint8Array(255)); + encryptService.decryptFileData.mockResolvedValue(new Uint8Array(255)); global.fetch = jest.fn(() => Promise.resolve({ @@ -362,7 +362,7 @@ describe("VaultExportService", () => { cipherView.attachments = [attachmentView]; cipherService.getAllDecrypted.mockResolvedValue([cipherView]); folderService.getAllDecryptedFromState.mockResolvedValue([]); - encryptService.decryptToBytes.mockResolvedValue(new Uint8Array(255)); + encryptService.decryptFileData.mockResolvedValue(new Uint8Array(255)); global.fetch = jest.fn(() => Promise.resolve({ status: 200, @@ -427,7 +427,7 @@ describe("VaultExportService", () => { }); it("has a mac property", async () => { - encryptService.encrypt.mockResolvedValue(mac); + encryptService.encryptString.mockResolvedValue(mac); exportedVault = await exportService.getPasswordProtectedExport(password); exportString = exportedVault.data; exportObject = JSON.parse(exportString); @@ -436,7 +436,7 @@ describe("VaultExportService", () => { }); it("has data property", async () => { - encryptService.encrypt.mockResolvedValue(data); + encryptService.encryptString.mockResolvedValue(data); exportedVault = await exportService.getPasswordProtectedExport(password); exportString = exportedVault.data; exportObject = JSON.parse(exportString); diff --git a/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.ts b/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.ts index 96b19acd963..8b66580d4cd 100644 --- a/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.ts +++ b/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.ts @@ -157,7 +157,7 @@ export class IndividualVaultExportService attachment.key != null ? attachment.key : await this.keyService.getOrgKey(cipher.organizationId); - return await this.encryptService.decryptToBytes(encBuf, key); + return await this.encryptService.decryptFileData(encBuf, key); } catch { throw new Error("Error decrypting attachment"); } @@ -220,7 +220,7 @@ export class IndividualVaultExportService await Promise.all(promises); const userKey = await this.keyService.getUserKeyWithLegacySupport(activeUserId); - const encKeyValidation = await this.encryptService.encrypt(Utils.newGuid(), userKey); + const encKeyValidation = await this.encryptService.encryptString(Utils.newGuid(), userKey); const jsonDoc: BitwardenEncryptedIndividualJsonExport = { encrypted: true, diff --git a/libs/tools/export/vault-export/vault-export-core/src/services/org-vault-export.service.ts b/libs/tools/export/vault-export/vault-export-core/src/services/org-vault-export.service.ts index 86edf67bf03..fc46915c15d 100644 --- a/libs/tools/export/vault-export/vault-export-core/src/services/org-vault-export.service.ts +++ b/libs/tools/export/vault-export/vault-export-core/src/services/org-vault-export.service.ts @@ -286,7 +286,7 @@ export class OrganizationVaultExportService ciphers: Cipher[], ): Promise { const orgKey = await this.keyService.getOrgKey(organizationId); - const encKeyValidation = await this.encryptService.encrypt(Utils.newGuid(), orgKey); + const encKeyValidation = await this.encryptService.encryptString(Utils.newGuid(), orgKey); const jsonDoc: BitwardenEncryptedOrgJsonExport = { encrypted: true, diff --git a/libs/tools/export/vault-export/vault-export-core/src/services/vault-export.service.spec.ts b/libs/tools/export/vault-export/vault-export-core/src/services/vault-export.service.spec.ts index a90f0a3ed7b..4e0dbfcc330 100644 --- a/libs/tools/export/vault-export/vault-export-core/src/services/vault-export.service.spec.ts +++ b/libs/tools/export/vault-export/vault-export-core/src/services/vault-export.service.spec.ts @@ -175,7 +175,7 @@ describe("VaultExportService", () => { folderService.folderViews$.mockReturnValue(of(UserFolderViews)); folderService.folders$.mockReturnValue(of(UserFolders)); kdfConfigService.getKdfConfig.mockResolvedValue(DEFAULT_KDF_CONFIG); - encryptService.encrypt.mockResolvedValue(new EncString("encrypted")); + encryptService.encryptString.mockResolvedValue(new EncString("encrypted")); keyService.userKey$.mockReturnValue(new BehaviorSubject("mockOriginalUserKey" as any)); const userId = "" as UserId; const accountInfo: AccountInfo = { @@ -282,7 +282,7 @@ describe("VaultExportService", () => { }); it("has a mac property", async () => { - encryptService.encrypt.mockResolvedValue(mac); + encryptService.encryptString.mockResolvedValue(mac); exportedVault = await exportService.getPasswordProtectedExport(password); @@ -293,7 +293,7 @@ describe("VaultExportService", () => { }); it("has data property", async () => { - encryptService.encrypt.mockResolvedValue(data); + encryptService.encryptString.mockResolvedValue(data); exportedVault = await exportService.getPasswordProtectedExport(password); diff --git a/libs/tools/generator/extensions/history/src/legacy-password-history-decryptor.ts b/libs/tools/generator/extensions/history/src/legacy-password-history-decryptor.ts index 06113ee9b99..4278f7e0e08 100644 --- a/libs/tools/generator/extensions/history/src/legacy-password-history-decryptor.ts +++ b/libs/tools/generator/extensions/history/src/legacy-password-history-decryptor.ts @@ -19,7 +19,7 @@ export class LegacyPasswordHistoryDecryptor { const promises = (history ?? []).map(async (item) => { const encrypted = new EncString(item.password); - const decrypted = await this.encryptService.decryptToUtf8(encrypted, key); + const decrypted = await this.encryptService.decryptString(encrypted, key); return new GeneratedPasswordHistory(decrypted, item.date); }); diff --git a/libs/tools/generator/extensions/history/src/local-generator-history.service.spec.ts b/libs/tools/generator/extensions/history/src/local-generator-history.service.spec.ts index b3dee69bdbf..3621b2c24a9 100644 --- a/libs/tools/generator/extensions/history/src/local-generator-history.service.spec.ts +++ b/libs/tools/generator/extensions/history/src/local-generator-history.service.spec.ts @@ -22,8 +22,10 @@ describe("LocalGeneratorHistoryService", () => { const userKey = new SymmetricCryptoKey(new Uint8Array(64) as CsprngArray) as UserKey; beforeEach(() => { - encryptService.encrypt.mockImplementation((p) => Promise.resolve(p as unknown as EncString)); - encryptService.decryptToUtf8.mockImplementation((c) => Promise.resolve(c.encryptedString)); + encryptService.encryptString.mockImplementation((p) => + Promise.resolve(p as unknown as EncString), + ); + encryptService.decryptString.mockImplementation((c) => Promise.resolve(c.encryptedString)); keyService.getUserKey.mockImplementation(() => Promise.resolve(userKey)); keyService.userKey$.mockImplementation(() => of(true as unknown as UserKey)); }); From 1fc5c206c38b7a157a4e95de48a74abecc757168 Mon Sep 17 00:00:00 2001 From: Daniel Riera Date: Wed, 30 Apr 2025 10:47:25 -0400 Subject: [PATCH 05/19] PM-21027-add-tooltip (#14564) --- .../src/autofill/content/components/cipher/cipher-info.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/browser/src/autofill/content/components/cipher/cipher-info.ts b/apps/browser/src/autofill/content/components/cipher/cipher-info.ts index e3d237b9bc6..df3f2d7fa16 100644 --- a/apps/browser/src/autofill/content/components/cipher/cipher-info.ts +++ b/apps/browser/src/autofill/content/components/cipher/cipher-info.ts @@ -14,7 +14,7 @@ export function CipherInfo({ cipher, theme }: { cipher: NotificationCipherData; return html`
- + ${[ name, hasIndicatorIcons From 106dd33ef4db9ed38caf2ac9b3c9661b8776f1b9 Mon Sep 17 00:00:00 2001 From: Jason Ng Date: Wed, 30 Apr 2025 12:16:09 -0400 Subject: [PATCH 06/19] [PM-18800] vault onboarding nudges and badge (#14278) * added empty vault nudge service and has items vault nudge service with spotlight and settings badge to vault v2 in browser * Refactor Vault Nudge Service for clarity between spotlight and badge dismissals --- apps/browser/src/_locales/en/messages.json | 21 ++++++ apps/browser/src/popup/tabs-v2.component.ts | 6 +- .../popup/settings/settings-v2.component.html | 21 +++++- .../popup/settings/settings-v2.component.ts | 34 +++++++++- .../vault-v2/vault-v2.component.html | 34 ++++++++-- .../components/vault-v2/vault-v2.component.ts | 59 +++++++++++++---- .../popup/services/intro-carousel.service.ts | 16 ++++- libs/vault/src/index.ts | 2 + .../empty-vault-nudge.service.ts | 64 +++++++++++++++++++ .../has-items-nudge.service.ts | 43 +++++++++---- .../has-nudge.service.ts | 18 ++++-- .../services/custom-nudges-services/index.ts | 1 + .../services/default-single-nudge.service.ts | 33 ++++++---- .../src/services/vault-nudges.service.spec.ts | 40 +++++++----- .../src/services/vault-nudges.service.ts | 43 +++++++++---- 15 files changed, 345 insertions(+), 90 deletions(-) create mode 100644 libs/vault/src/services/custom-nudges-services/empty-vault-nudge.service.ts diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 4f83b07506b..5c9e829e82f 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -5201,6 +5201,12 @@ "changeAtRiskPassword": { "message": "Change at-risk password" }, + "settingsVaultOptions": { + "message": "Vault options" + }, + "emptyVaultDescription": { + "message": "The vault protects more than just your passwords. Store secure logins, IDs, cards and notes securely here." + }, "introCarouselLabel": { "message": "Welcome to Bitwarden" }, @@ -5227,5 +5233,20 @@ }, "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." + }, + "emptyVaultNudgeTitle": { + "message": "Import existing passwords" + }, + "emptyVaultNudgeBody": { + "message": "Use the importer to quickly transfer logins to Bitwarden without manually adding them." + }, + "emptyVaultNudgeButton": { + "message": "Import now" + }, + "hasItemsVaultNudgeTitle": { + "message": "Welcome to your vault!" + }, + "hasItemsVaultNudgeBody": { + "message": "Autofill items for the current page\nFavorite items for easy access\nSearch your vault for something else" } } \ No newline at end of file diff --git a/apps/browser/src/popup/tabs-v2.component.ts b/apps/browser/src/popup/tabs-v2.component.ts index 1392dc565ab..24ce9d8cb12 100644 --- a/apps/browser/src/popup/tabs-v2.component.ts +++ b/apps/browser/src/popup/tabs-v2.component.ts @@ -18,9 +18,9 @@ export class TabsV2Component { protected navButtons$ = combineLatest([ this.configService.getFeatureFlag$(FeatureFlag.PM8851_BrowserOnboardingNudge), - this.hasNudgeService.shouldShowNudge$(), + this.hasNudgeService.nudgeStatus$(), ]).pipe( - map(([onboardingFeatureEnabled, showNudge]) => { + map(([onboardingFeatureEnabled, nudgeStatus]) => { return [ { label: "vault", @@ -45,7 +45,7 @@ export class TabsV2Component { page: "/tabs/settings", iconKey: "cog", iconKeyActive: "cog-f", - showBerry: onboardingFeatureEnabled && showNudge, + showBerry: onboardingFeatureEnabled && !nudgeStatus.hasSpotlightDismissed, }, ]; }), diff --git a/apps/browser/src/tools/popup/settings/settings-v2.component.html b/apps/browser/src/tools/popup/settings/settings-v2.component.html index 26aeea4f20a..b6f98b649fe 100644 --- a/apps/browser/src/tools/popup/settings/settings-v2.component.html +++ b/apps/browser/src/tools/popup/settings/settings-v2.component.html @@ -29,9 +29,26 @@ - + - {{ "vault" | i18n }} +
+

{{ "settingsVaultOptions" | i18n }}

+ + 1 +
+
diff --git a/apps/browser/src/tools/popup/settings/settings-v2.component.ts b/apps/browser/src/tools/popup/settings/settings-v2.component.ts index 5f3eb1c8f12..737d79ea4ca 100644 --- a/apps/browser/src/tools/popup/settings/settings-v2.component.ts +++ b/apps/browser/src/tools/popup/settings/settings-v2.component.ts @@ -1,9 +1,14 @@ import { CommonModule } from "@angular/common"; -import { Component } from "@angular/core"; +import { Component, OnInit } from "@angular/core"; import { RouterModule } from "@angular/router"; +import { firstValueFrom, Observable } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; -import { ItemModule } from "@bitwarden/components"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { getUserId } from "@bitwarden/common/auth/services/account.service"; +import { UserId } from "@bitwarden/common/types/guid"; +import { BadgeComponent, ItemModule } from "@bitwarden/components"; +import { NudgeStatus, VaultNudgesService, VaultNudgeType } from "@bitwarden/vault"; import { CurrentAccountComponent } from "../../../auth/popup/account-switching/current-account.component"; import { PopOutComponent } from "../../../platform/popup/components/pop-out.component"; @@ -22,6 +27,29 @@ import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.co PopOutComponent, ItemModule, CurrentAccountComponent, + BadgeComponent, ], }) -export class SettingsV2Component {} +export class SettingsV2Component implements OnInit { + VaultNudgeType = VaultNudgeType; + showVaultBadge$: Observable = new Observable(); + activeUserId: UserId | null = null; + + constructor( + private readonly vaultNudgesService: VaultNudgesService, + private readonly accountService: AccountService, + ) {} + async ngOnInit() { + this.activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + this.showVaultBadge$ = this.vaultNudgesService.showNudge$( + VaultNudgeType.EmptyVaultNudge, + this.activeUserId, + ); + } + + async dismissBadge(type: VaultNudgeType) { + if (!(await firstValueFrom(this.showVaultBadge$)).hasBadgeDismissed) { + await this.vaultNudgesService.dismissNudge(type, this.activeUserId as UserId, true); + } + } +} diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.html b/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.html index 2a50eb43960..7d04f23795e 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.html +++ b/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.html @@ -14,7 +14,9 @@ > {{ "yourVaultIsEmpty" | i18n }} - {{ "autofillSuggestionsTip" | i18n }} + +

{{ "emptyVaultDescription" | i18n }}

+
- - - + + + + + + +
+ + +
+ + +
diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.ts b/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.ts index 7f5242dcf18..64805a02394 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.ts @@ -2,30 +2,38 @@ import { CdkVirtualScrollableElement, ScrollingModule } from "@angular/cdk/scrol import { CommonModule } from "@angular/common"; import { AfterViewInit, Component, DestroyRef, OnDestroy, OnInit, ViewChild } from "@angular/core"; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { Router, RouterModule } from "@angular/router"; import { combineLatest, filter, - map, firstValueFrom, + map, Observable, shareReplay, + startWith, switchMap, take, - startWith, } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; -import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; -import { CipherId, CollectionId, OrganizationId } from "@bitwarden/common/types/guid"; +import { CipherId, CollectionId, OrganizationId, UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CipherType } from "@bitwarden/common/vault/enums"; import { ButtonModule, DialogService, Icons, NoItemsModule } from "@bitwarden/components"; -import { DecryptionFailureDialogComponent, VaultIcons } from "@bitwarden/vault"; +import { + DecryptionFailureDialogComponent, + SpotlightComponent, + VaultIcons, + VaultNudgesService, + VaultNudgeType, +} from "@bitwarden/vault"; import { CurrentAccountComponent } from "../../../../auth/popup/account-switching/current-account.component"; +import { BrowserApi } from "../../../../platform/browser/browser-api"; +import BrowserPopupUtils from "../../../../platform/popup/browser-popup-utils"; import { PopOutComponent } from "../../../../platform/popup/components/pop-out.component"; import { PopupHeaderComponent } from "../../../../platform/popup/layout/popup-header.component"; import { PopupPageComponent } from "../../../../platform/popup/layout/popup-page.component"; @@ -74,14 +82,29 @@ enum VaultState { VaultHeaderV2Component, AtRiskPasswordCalloutComponent, NewSettingsCalloutComponent, + SpotlightComponent, + RouterModule, ], providers: [VaultPageService], }) export class VaultV2Component implements OnInit, AfterViewInit, OnDestroy { @ViewChild(CdkVirtualScrollableElement) virtualScrollElement?: CdkVirtualScrollableElement; + VaultNudgeType = VaultNudgeType; cipherType = CipherType; + private activeUserId$ = this.accountService.activeAccount$.pipe(getUserId); + showEmptyVaultSpotlight$: Observable = this.activeUserId$.pipe( + switchMap((userId) => + this.vaultNudgesService.showNudge$(VaultNudgeType.EmptyVaultNudge, userId), + ), + map((nudgeStatus) => !nudgeStatus.hasSpotlightDismissed), + ); + showHasItemsVaultSpotlight$: Observable = this.activeUserId$.pipe( + switchMap((userId) => this.vaultNudgesService.showNudge$(VaultNudgeType.HasVaultItems, userId)), + map((nudgeStatus) => !nudgeStatus.hasSpotlightDismissed), + ); + activeUserId: UserId | null = null; protected favoriteCiphers$ = this.vaultPopupItemsService.favoriteCiphers$; protected remainingCiphers$ = this.vaultPopupItemsService.remainingCiphers$; protected allFilters$ = this.vaultPopupListFiltersService.allFilters$; @@ -131,7 +154,8 @@ export class VaultV2Component implements OnInit, AfterViewInit, OnDestroy { private dialogService: DialogService, private vaultCopyButtonsService: VaultPopupCopyButtonsService, private introCarouselService: IntroCarouselService, - private configService: ConfigService, + private vaultNudgesService: VaultNudgesService, + private router: Router, ) { combineLatest([ this.vaultPopupItemsService.emptyVault$, @@ -169,16 +193,12 @@ export class VaultV2Component implements OnInit, AfterViewInit, OnDestroy { } async ngOnInit() { - const hasVaultNudgeFlag = await this.configService.getFeatureFlag( - FeatureFlag.PM8851_BrowserOnboardingNudge, - ); - if (hasVaultNudgeFlag) { - await this.introCarouselService.setIntroCarouselDismissed(); - } - const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + this.activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + + await this.introCarouselService.setIntroCarouselDismissed(); this.cipherService - .failedToDecryptCiphers$(activeUserId) + .failedToDecryptCiphers$(this.activeUserId) .pipe( map((ciphers) => (ciphers ? ciphers.filter((c) => !c.isDeleted) : [])), filter((ciphers) => ciphers.length > 0), @@ -196,5 +216,16 @@ export class VaultV2Component implements OnInit, AfterViewInit, OnDestroy { this.vaultScrollPositionService.stop(); } + async navigateToImport() { + await this.router.navigate(["/import"]); + if (await BrowserApi.isPopupOpen()) { + await BrowserPopupUtils.openCurrentPagePopout(window); + } + } + + async dismissVaultNudgeSpotlight(type: VaultNudgeType) { + await this.vaultNudgesService.dismissNudge(type, this.activeUserId as UserId); + } + protected readonly FeatureFlag = FeatureFlag; } diff --git a/apps/browser/src/vault/popup/services/intro-carousel.service.ts b/apps/browser/src/vault/popup/services/intro-carousel.service.ts index 2c523c5a93c..7d2bb7dedb9 100644 --- a/apps/browser/src/vault/popup/services/intro-carousel.service.ts +++ b/apps/browser/src/vault/popup/services/intro-carousel.service.ts @@ -1,6 +1,8 @@ import { Injectable } from "@angular/core"; -import { map, Observable } from "rxjs"; +import { firstValueFrom, map, Observable } from "rxjs"; +import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { GlobalState, KeyDefinition, @@ -26,9 +28,17 @@ export class IntroCarouselService { map((x) => x ?? false), ); - constructor(private stateProvider: StateProvider) {} + constructor( + private stateProvider: StateProvider, + private configService: ConfigService, + ) {} async setIntroCarouselDismissed(): Promise { - await this.introCarouselState.update(() => true); + const hasVaultNudgeFlag = await firstValueFrom( + this.configService.getFeatureFlag$(FeatureFlag.PM8851_BrowserOnboardingNudge), + ); + if (hasVaultNudgeFlag) { + await this.introCarouselState.update(() => true); + } } } diff --git a/libs/vault/src/index.ts b/libs/vault/src/index.ts index 6e5a452ec8c..87e15b18676 100644 --- a/libs/vault/src/index.ts +++ b/libs/vault/src/index.ts @@ -32,3 +32,5 @@ export { SshImportPromptService } from "./services/ssh-import-prompt.service"; export * from "./abstractions/change-login-password.service"; export * from "./services/default-change-login-password.service"; + +export { SpotlightComponent } from "./components/spotlight/spotlight.component"; diff --git a/libs/vault/src/services/custom-nudges-services/empty-vault-nudge.service.ts b/libs/vault/src/services/custom-nudges-services/empty-vault-nudge.service.ts new file mode 100644 index 00000000000..556e389b288 --- /dev/null +++ b/libs/vault/src/services/custom-nudges-services/empty-vault-nudge.service.ts @@ -0,0 +1,64 @@ +import { inject, Injectable } from "@angular/core"; +import { combineLatest, Observable, of, switchMap } from "rxjs"; + +import { CollectionService } from "@bitwarden/admin-console/common"; +import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; +import { UserId } from "@bitwarden/common/types/guid"; +import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; + +import { DefaultSingleNudgeService } from "../default-single-nudge.service"; +import { NudgeStatus, VaultNudgeType } from "../vault-nudges.service"; + +/** + * Custom Nudge Service Checking Nudge Status For Empty Vault + */ +@Injectable({ + providedIn: "root", +}) +export class EmptyVaultNudgeService extends DefaultSingleNudgeService { + cipherService = inject(CipherService); + organizationService = inject(OrganizationService); + collectionService = inject(CollectionService); + + nudgeStatus$(nudgeType: VaultNudgeType, userId: UserId): Observable { + return combineLatest([ + this.getNudgeStatus$(nudgeType, userId), + this.cipherService.cipherViews$(userId), + this.organizationService.organizations$(userId), + this.collectionService.decryptedCollections$, + ]).pipe( + switchMap(([nudgeStatus, ciphers, orgs, collections]) => { + const emptyVault = ciphers == null || ciphers.length === 0; + if (orgs == null || orgs.length === 0) { + return nudgeStatus.hasBadgeDismissed || nudgeStatus.hasSpotlightDismissed + ? of(nudgeStatus) + : of({ + hasSpotlightDismissed: emptyVault, + hasBadgeDismissed: emptyVault, + }); + } + const orgIds = new Set(orgs.map((org) => org.id)); + const canCreateCollections = orgs.some((org) => org.canCreateNewCollections); + const hasManageCollections = collections.some( + (c) => c.manage && orgIds.has(c.organizationId), + ); + // Do not show nudge when + // user has previously dismissed nudge + // OR + // user belongs to an organization and cannot create collections || manage collections + if ( + nudgeStatus.hasBadgeDismissed || + nudgeStatus.hasSpotlightDismissed || + hasManageCollections || + canCreateCollections + ) { + return of(nudgeStatus); + } + return of({ + hasSpotlightDismissed: emptyVault, + hasBadgeDismissed: emptyVault, + }); + }), + ); + } +} diff --git a/libs/vault/src/services/custom-nudges-services/has-items-nudge.service.ts b/libs/vault/src/services/custom-nudges-services/has-items-nudge.service.ts index 144b15d61f4..6b5ac7eba00 100644 --- a/libs/vault/src/services/custom-nudges-services/has-items-nudge.service.ts +++ b/libs/vault/src/services/custom-nudges-services/has-items-nudge.service.ts @@ -1,30 +1,49 @@ import { inject, Injectable } from "@angular/core"; -import { map, Observable, of, switchMap } from "rxjs"; +import { combineLatest, Observable, switchMap } from "rxjs"; +import { VaultProfileService } from "@bitwarden/angular/vault/services/vault-profile.service"; +import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { DefaultSingleNudgeService } from "../default-single-nudge.service"; -import { VaultNudgeType } from "../vault-nudges.service"; +import { NudgeStatus, VaultNudgeType } from "../vault-nudges.service"; /** - * Custom Nudge Service to use for the Onboarding Nudges in the Vault + * Custom Nudge Service Checking Nudge Status For Welcome Nudge With Populated Vault */ @Injectable({ providedIn: "root", }) export class HasItemsNudgeService extends DefaultSingleNudgeService { cipherService = inject(CipherService); + vaultProfileService = inject(VaultProfileService); + logService = inject(LogService); - shouldShowNudge$(nudgeType: VaultNudgeType, userId: UserId): Observable { - return this.isDismissed$(nudgeType, userId).pipe( - switchMap((dismissed) => - dismissed - ? of(false) - : this.cipherService - .cipherViews$(userId) - .pipe(map((ciphers) => ciphers == null || ciphers.length === 0)), - ), + nudgeStatus$(nudgeType: VaultNudgeType, userId: UserId): Observable { + return combineLatest([ + this.cipherService.cipherViews$(userId), + this.getNudgeStatus$(nudgeType, userId), + ]).pipe( + switchMap(async ([ciphers, nudgeStatus]) => { + try { + const creationDate = await this.vaultProfileService.getProfileCreationDate(userId); + const thirtyDays = new Date(new Date().getTime() - 30 * 24 * 60 * 60 * 1000); + const isRecentAcct = creationDate >= thirtyDays; + + if (!isRecentAcct || nudgeStatus.hasSpotlightDismissed) { + return nudgeStatus; + } else { + return { + hasBadgeDismissed: ciphers == null || ciphers.length === 0, + hasSpotlightDismissed: ciphers == null || ciphers.length === 0, + }; + } + } catch (error) { + this.logService.error("Failed to fetch profile creation date: ", error); + return nudgeStatus; + } + }), ); } } diff --git a/libs/vault/src/services/custom-nudges-services/has-nudge.service.ts b/libs/vault/src/services/custom-nudges-services/has-nudge.service.ts index b1f319451e6..0c14cff002f 100644 --- a/libs/vault/src/services/custom-nudges-services/has-nudge.service.ts +++ b/libs/vault/src/services/custom-nudges-services/has-nudge.service.ts @@ -5,7 +5,7 @@ import { AccountService } from "@bitwarden/common/auth/abstractions/account.serv import { UserId } from "@bitwarden/common/types/guid"; import { DefaultSingleNudgeService } from "../default-single-nudge.service"; -import { VaultNudgeType } from "../vault-nudges.service"; +import { NudgeStatus, VaultNudgeType } from "../vault-nudges.service"; /** * Custom Nudge Service used for showing if the user has any existing nudge in the Vault. @@ -17,6 +17,7 @@ export class HasNudgeService extends DefaultSingleNudgeService { private accountService = inject(AccountService); private nudgeTypes: VaultNudgeType[] = [ + VaultNudgeType.EmptyVaultNudge, VaultNudgeType.HasVaultItems, VaultNudgeType.IntroCarouselDismissal, // add additional nudge types here as needed @@ -25,20 +26,25 @@ export class HasNudgeService extends DefaultSingleNudgeService { /** * Returns an observable that emits true if any of the provided nudge types are present */ - shouldShowNudge$(): Observable { + nudgeStatus$(): Observable { return this.accountService.activeAccount$.pipe( switchMap((activeAccount) => { const userId: UserId | undefined = activeAccount?.id; if (!userId) { - return of(false); + return of({ hasBadgeDismissed: true, hasSpotlightDismissed: true }); } - const nudgeObservables: Observable[] = this.nudgeTypes.map((nudge) => - super.shouldShowNudge$(nudge, userId), + const nudgeObservables: Observable[] = this.nudgeTypes.map((nudge) => + super.nudgeStatus$(nudge, userId), ); return combineLatest(nudgeObservables).pipe( - map((nudgeStates) => nudgeStates.some((state) => state)), + map((nudgeStates) => { + return { + hasBadgeDismissed: true, + hasSpotlightDismissed: nudgeStates.some((state) => state.hasSpotlightDismissed), + }; + }), distinctUntilChanged(), ); }), diff --git a/libs/vault/src/services/custom-nudges-services/index.ts b/libs/vault/src/services/custom-nudges-services/index.ts index dd343e47d75..9a1f0acd420 100644 --- a/libs/vault/src/services/custom-nudges-services/index.ts +++ b/libs/vault/src/services/custom-nudges-services/index.ts @@ -1,2 +1,3 @@ export * from "./has-items-nudge.service"; +export * from "./empty-vault-nudge.service"; export * from "./has-nudge.service"; diff --git a/libs/vault/src/services/default-single-nudge.service.ts b/libs/vault/src/services/default-single-nudge.service.ts index 0fd48b63c8d..9a1759cab38 100644 --- a/libs/vault/src/services/default-single-nudge.service.ts +++ b/libs/vault/src/services/default-single-nudge.service.ts @@ -4,15 +4,19 @@ import { map, Observable } from "rxjs"; import { StateProvider } from "@bitwarden/common/platform/state"; import { UserId } from "@bitwarden/common/types/guid"; -import { VAULT_NUDGE_DISMISSED_DISK_KEY, VaultNudgeType } from "./vault-nudges.service"; +import { + NudgeStatus, + VAULT_NUDGE_DISMISSED_DISK_KEY, + VaultNudgeType, +} from "./vault-nudges.service"; /** * Base interface for handling a nudge's status */ export interface SingleNudgeService { - shouldShowNudge$(nudgeType: VaultNudgeType, userId: UserId): Observable; + nudgeStatus$(nudgeType: VaultNudgeType, userId: UserId): Observable; - setNudgeStatus(nudgeType: VaultNudgeType, dismissed: boolean, userId: UserId): Promise; + setNudgeStatus(nudgeType: VaultNudgeType, newStatus: NudgeStatus, userId: UserId): Promise; } /** @@ -24,28 +28,29 @@ export interface SingleNudgeService { export class DefaultSingleNudgeService implements SingleNudgeService { stateProvider = inject(StateProvider); - protected isDismissed$(nudgeType: VaultNudgeType, userId: UserId): Observable { + protected getNudgeStatus$(nudgeType: VaultNudgeType, userId: UserId): Observable { return this.stateProvider .getUser(userId, VAULT_NUDGE_DISMISSED_DISK_KEY) - .state$.pipe(map((nudges) => nudges?.includes(nudgeType) ?? false)); + .state$.pipe( + map( + (nudges) => + nudges?.[nudgeType] ?? { hasBadgeDismissed: false, hasSpotlightDismissed: false }, + ), + ); } - shouldShowNudge$(nudgeType: VaultNudgeType, userId: UserId): Observable { - return this.isDismissed$(nudgeType, userId).pipe(map((dismissed) => !dismissed)); + nudgeStatus$(nudgeType: VaultNudgeType, userId: UserId): Observable { + return this.getNudgeStatus$(nudgeType, userId); } async setNudgeStatus( nudgeType: VaultNudgeType, - dismissed: boolean, + status: NudgeStatus, userId: UserId, ): Promise { await this.stateProvider.getUser(userId, VAULT_NUDGE_DISMISSED_DISK_KEY).update((nudges) => { - nudges ??= []; - if (dismissed) { - nudges.push(nudgeType); - } else { - nudges = nudges.filter((n) => n !== nudgeType); - } + nudges ??= {}; + nudges[nudgeType] = status; return nudges; }); } diff --git a/libs/vault/src/services/vault-nudges.service.spec.ts b/libs/vault/src/services/vault-nudges.service.spec.ts index 0d376f37cf9..a01cac94fb1 100644 --- a/libs/vault/src/services/vault-nudges.service.spec.ts +++ b/libs/vault/src/services/vault-nudges.service.spec.ts @@ -2,12 +2,13 @@ import { TestBed } from "@angular/core/testing"; import { mock } from "jest-mock-extended"; import { firstValueFrom, of } from "rxjs"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { StateProvider } from "@bitwarden/common/platform/state"; import { UserId } from "@bitwarden/common/types/guid"; import { FakeStateProvider, mockAccountServiceWith } from "../../../common/spec"; -import { HasItemsNudgeService } from "./custom-nudges-services/has-items-nudge.service"; +import { HasItemsNudgeService, EmptyVaultNudgeService } from "./custom-nudges-services"; import { DefaultSingleNudgeService } from "./default-single-nudge.service"; import { VaultNudgesService, VaultNudgeType } from "./vault-nudges.service"; @@ -15,6 +16,10 @@ describe("Vault Nudges Service", () => { let fakeStateProvider: FakeStateProvider; let testBed: TestBed; + const mockConfigService = { + getFeatureFlag$: jest.fn().mockReturnValue(of(true)), + getFeatureFlag: jest.fn().mockReturnValue(true), + }; beforeEach(async () => { fakeStateProvider = new FakeStateProvider(mockAccountServiceWith("user-id" as UserId)); @@ -32,50 +37,55 @@ describe("Vault Nudges Service", () => { provide: StateProvider, useValue: fakeStateProvider, }, + { provide: ConfigService, useValue: mockConfigService }, { provide: HasItemsNudgeService, useValue: mock(), }, + { + provide: EmptyVaultNudgeService, + useValue: mock(), + }, ], }); }); describe("DefaultSingleNudgeService", () => { - it("should return shouldShowNudge === false when IntroCaourselDismissal dismissed is true", async () => { + it("should return hasSpotlightDismissed === true when EmptyVaultNudge dismissed is true", async () => { const service = testBed.inject(DefaultSingleNudgeService); await service.setNudgeStatus( - VaultNudgeType.IntroCarouselDismissal, - true, + VaultNudgeType.EmptyVaultNudge, + { hasBadgeDismissed: true, hasSpotlightDismissed: true }, "user-id" as UserId, ); const result = await firstValueFrom( - service.shouldShowNudge$(VaultNudgeType.IntroCarouselDismissal, "user-id" as UserId), + service.nudgeStatus$(VaultNudgeType.EmptyVaultNudge, "user-id" as UserId), ); - expect(result).toBe(false); + expect(result).toEqual({ hasBadgeDismissed: true, hasSpotlightDismissed: true }); }); - it("should return shouldShowNudge === true when IntroCaourselDismissal dismissed is false", async () => { + it("should return hasSpotlightDismissed === true when EmptyVaultNudge dismissed is false", async () => { const service = testBed.inject(DefaultSingleNudgeService); await service.setNudgeStatus( - VaultNudgeType.IntroCarouselDismissal, - false, + VaultNudgeType.EmptyVaultNudge, + { hasBadgeDismissed: false, hasSpotlightDismissed: false }, "user-id" as UserId, ); const result = await firstValueFrom( - service.shouldShowNudge$(VaultNudgeType.IntroCarouselDismissal, "user-id" as UserId), + service.nudgeStatus$(VaultNudgeType.EmptyVaultNudge, "user-id" as UserId), ); - expect(result).toBe(true); + expect(result).toEqual({ hasBadgeDismissed: false, hasSpotlightDismissed: false }); }); }); describe("VaultNudgesService", () => { - it("should return true, the proper value from the custom nudge service shouldShowNudge$", async () => { + it("should return true, the proper value from the custom nudge service nudgeStatus$", async () => { TestBed.overrideProvider(HasItemsNudgeService, { - useValue: { shouldShowNudge$: () => of(true) }, + useValue: { nudgeStatus$: () => of(true) }, }); const service = testBed.inject(VaultNudgesService); @@ -86,9 +96,9 @@ describe("Vault Nudges Service", () => { expect(result).toBe(true); }); - it("should return false, the proper value for the custom nudge service shouldShowNudge$", async () => { + it("should return false, the proper value for the custom nudge service nudgeStatus$", async () => { TestBed.overrideProvider(HasItemsNudgeService, { - useValue: { shouldShowNudge$: () => of(false) }, + useValue: { nudgeStatus$: () => of(false) }, }); const service = testBed.inject(VaultNudgesService); diff --git a/libs/vault/src/services/vault-nudges.service.ts b/libs/vault/src/services/vault-nudges.service.ts index 0a031f8c092..28198d17068 100644 --- a/libs/vault/src/services/vault-nudges.service.ts +++ b/libs/vault/src/services/vault-nudges.service.ts @@ -1,11 +1,19 @@ import { inject, Injectable } from "@angular/core"; +import { of, switchMap } from "rxjs"; +import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { UserKeyDefinition, VAULT_NUDGES_DISK } from "@bitwarden/common/platform/state"; import { UserId } from "@bitwarden/common/types/guid"; -import { HasItemsNudgeService } from "./custom-nudges-services/has-items-nudge.service"; +import { HasItemsNudgeService, EmptyVaultNudgeService } from "./custom-nudges-services"; import { DefaultSingleNudgeService, SingleNudgeService } from "./default-single-nudge.service"; +export type NudgeStatus = { + hasBadgeDismissed: boolean; + hasSpotlightDismissed: boolean; +}; + /** * Enum to list the various nudge types, to be used by components/badges to show/hide the nudge */ @@ -13,18 +21,17 @@ export enum VaultNudgeType { /** Nudge to show when user has no items in their vault * Add future nudges here */ + EmptyVaultNudge = "empty-vault-nudge", HasVaultItems = "has-vault-items", IntroCarouselDismissal = "intro-carousel-dismissal", } -export const VAULT_NUDGE_DISMISSED_DISK_KEY = new UserKeyDefinition( - VAULT_NUDGES_DISK, - "vaultNudgeDismissed", - { - deserializer: (nudgeDismissed) => nudgeDismissed, - clearOn: [], // Do not clear dismissals - }, -); +export const VAULT_NUDGE_DISMISSED_DISK_KEY = new UserKeyDefinition< + Partial> +>(VAULT_NUDGES_DISK, "vaultNudgeDismissed", { + deserializer: (nudge) => nudge, + clearOn: [], // Do not clear dismissals +}); @Injectable({ providedIn: "root", @@ -37,6 +44,7 @@ export class VaultNudgesService { */ private customNudgeServices: any = { [VaultNudgeType.HasVaultItems]: inject(HasItemsNudgeService), + [VaultNudgeType.EmptyVaultNudge]: inject(EmptyVaultNudgeService), }; /** @@ -45,6 +53,7 @@ export class VaultNudgesService { * @private */ private defaultNudgeService = inject(DefaultSingleNudgeService); + private configService = inject(ConfigService); private getNudgeService(nudge: VaultNudgeType): SingleNudgeService { return this.customNudgeServices[nudge] ?? this.defaultNudgeService; @@ -56,7 +65,14 @@ export class VaultNudgesService { * @param userId */ showNudge$(nudge: VaultNudgeType, userId: UserId) { - return this.getNudgeService(nudge).shouldShowNudge$(nudge, userId); + return this.configService.getFeatureFlag$(FeatureFlag.PM8851_BrowserOnboardingNudge).pipe( + switchMap((hasVaultNudgeFlag) => { + if (!hasVaultNudgeFlag) { + return of({ hasBadgeDismissed: true, hasSpotlightDismissed: true } as NudgeStatus); + } + return this.getNudgeService(nudge).nudgeStatus$(nudge, userId); + }), + ); } /** @@ -64,7 +80,10 @@ export class VaultNudgesService { * @param nudge * @param userId */ - dismissNudge(nudge: VaultNudgeType, userId: UserId) { - return this.getNudgeService(nudge).setNudgeStatus(nudge, true, userId); + async dismissNudge(nudge: VaultNudgeType, userId: UserId, onlyBadge: boolean = false) { + const dismissedStatus = onlyBadge + ? { hasBadgeDismissed: true, hasSpotlightDismissed: false } + : { hasBadgeDismissed: true, hasSpotlightDismissed: true }; + await this.getNudgeService(nudge).setNudgeStatus(nudge, dismissedStatus, userId); } } From e6530ade010a734427cd21891ec59cb13b09c07f Mon Sep 17 00:00:00 2001 From: Bryan Cunningham Date: Wed, 30 Apr 2025 14:24:12 -0400 Subject: [PATCH 07/19] Use small buttons in extension header (#14433) * use small button in extension vault header * use small button in extension folder settings * use small button in send header --- .../new-item-dropdown/new-item-dropdown-v2.component.html | 2 +- .../src/vault/popup/settings/folders-v2.component.html | 8 +++++++- .../new-send-dropdown/new-send-dropdown.component.html | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/apps/browser/src/vault/popup/components/vault-v2/new-item-dropdown/new-item-dropdown-v2.component.html b/apps/browser/src/vault/popup/components/vault-v2/new-item-dropdown/new-item-dropdown-v2.component.html index c952260a9a9..af627e22ef2 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/new-item-dropdown/new-item-dropdown-v2.component.html +++ b/apps/browser/src/vault/popup/components/vault-v2/new-item-dropdown/new-item-dropdown-v2.component.html @@ -1,4 +1,4 @@ - diff --git a/apps/browser/src/vault/popup/settings/folders-v2.component.html b/apps/browser/src/vault/popup/settings/folders-v2.component.html index 35a0fbec0a9..552547c0230 100644 --- a/apps/browser/src/vault/popup/settings/folders-v2.component.html +++ b/apps/browser/src/vault/popup/settings/folders-v2.component.html @@ -1,7 +1,13 @@ - diff --git a/libs/tools/send/send-ui/src/new-send-dropdown/new-send-dropdown.component.html b/libs/tools/send/send-ui/src/new-send-dropdown/new-send-dropdown.component.html index 344348f6a90..c39d95616f6 100644 --- a/libs/tools/send/send-ui/src/new-send-dropdown/new-send-dropdown.component.html +++ b/libs/tools/send/send-ui/src/new-send-dropdown/new-send-dropdown.component.html @@ -1,4 +1,4 @@ - From e596584e87109a1e96c311d550e06ff48ee88562 Mon Sep 17 00:00:00 2001 From: Vijay Oommen Date: Thu, 1 May 2025 08:03:32 -0500 Subject: [PATCH 08/19] [PM-20505] Weak-passwords-report: refresh rows after edit (#14401) --- .../reports/pages/cipher-report.component.ts | 8 +- .../pages/weak-passwords-report.component.ts | 146 ++++++++++++------ ...dmin-console-cipher-form-config.service.ts | 2 +- 3 files changed, 107 insertions(+), 49 deletions(-) diff --git a/apps/web/src/app/tools/reports/pages/cipher-report.component.ts b/apps/web/src/app/tools/reports/pages/cipher-report.component.ts index 0ad8a0a519c..ceda7b1c480 100644 --- a/apps/web/src/app/tools/reports/pages/cipher-report.component.ts +++ b/apps/web/src/app/tools/reports/pages/cipher-report.component.ts @@ -67,7 +67,7 @@ export class CipherReportComponent implements OnDestroy { protected i18nService: I18nService, private syncService: SyncService, private cipherFormConfigService: CipherFormConfigService, - private adminConsoleCipherFormConfigService: AdminConsoleCipherFormConfigService, + protected adminConsoleCipherFormConfigService: AdminConsoleCipherFormConfigService, ) { this.organizations$ = this.accountService.activeAccount$.pipe( getUserId, @@ -207,7 +207,7 @@ export class CipherReportComponent implements OnDestroy { // If the dialog was closed by deleting the cipher, refresh the report. if (result === VaultItemDialogResult.Deleted || result === VaultItemDialogResult.Saved) { - await this.load(); + await this.refresh(result, cipher); } } @@ -215,6 +215,10 @@ export class CipherReportComponent implements OnDestroy { this.allCiphers = []; } + protected async refresh(result: VaultItemDialogResult, cipher: CipherView) { + await this.load(); + } + protected async repromptCipher(c: CipherView) { return ( c.reprompt === CipherRepromptType.None || diff --git a/apps/web/src/app/tools/reports/pages/weak-passwords-report.component.ts b/apps/web/src/app/tools/reports/pages/weak-passwords-report.component.ts index f7631e37a7d..4144c9ac20f 100644 --- a/apps/web/src/app/tools/reports/pages/weak-passwords-report.component.ts +++ b/apps/web/src/app/tools/reports/pages/weak-passwords-report.component.ts @@ -1,18 +1,22 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore import { Component, OnInit } from "@angular/core"; +import { firstValueFrom } from "rxjs"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength"; +import { CipherId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { CipherType } from "@bitwarden/common/vault/enums"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { BadgeVariant, DialogService } from "@bitwarden/components"; import { CipherFormConfigService, PasswordRepromptService } from "@bitwarden/vault"; +import { VaultItemDialogResult } from "@bitwarden/web-vault/app/vault/components/vault-item-dialog/vault-item-dialog.component"; import { AdminConsoleCipherFormConfigService } from "../../../vault/org-vault/services/admin-console-cipher-form-config.service"; @@ -40,7 +44,7 @@ export class WeakPasswordsReportComponent extends CipherReportComponent implemen i18nService: I18nService, syncService: SyncService, cipherFormConfigService: CipherFormConfigService, - adminConsoleCipherFormConfigService: AdminConsoleCipherFormConfigService, + protected adminConsoleCipherFormConfigService: AdminConsoleCipherFormConfigService, ) { super( cipherService, @@ -66,62 +70,112 @@ export class WeakPasswordsReportComponent extends CipherReportComponent implemen this.findWeakPasswords(allCiphers); } - protected findWeakPasswords(ciphers: CipherView[]): void { - ciphers.forEach((ciph) => { - const { type, login, isDeleted, edit, viewPassword } = ciph; - if ( - type !== CipherType.Login || - login.password == null || - login.password === "" || - isDeleted || - (!this.organization && !edit) || - !viewPassword - ) { + protected async refresh(result: VaultItemDialogResult, cipher: CipherView) { + if (result === VaultItemDialogResult.Deleted) { + // remove the cipher from the list + this.weakPasswordCiphers = this.weakPasswordCiphers.filter((c) => c.id !== cipher.id); + this.filterCiphersByOrg(this.weakPasswordCiphers); + return; + } + + if (result == VaultItemDialogResult.Saved) { + const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); + let updatedCipher = await this.cipherService.get(cipher.id, activeUserId); + + if (this.isAdminConsoleActive) { + updatedCipher = await this.adminConsoleCipherFormConfigService.getCipher( + cipher.id as CipherId, + this.organization, + ); + } + + const updatedCipherView = await updatedCipher.decrypt( + await this.cipherService.getKeyForCipherKeyDecryption(updatedCipher, activeUserId), + ); + // update the cipher views + const updatedReportResult = this.determineWeakPasswordScore(updatedCipherView); + const index = this.weakPasswordCiphers.findIndex((c) => c.id === updatedCipherView.id); + + if (updatedReportResult == null) { + // the password is no longer weak + // remove the cipher from the list + this.weakPasswordCiphers.splice(index, 1); + this.filterCiphersByOrg(this.weakPasswordCiphers); return; } - const hasUserName = this.isUserNameNotEmpty(ciph); - let userInput: string[] = []; - if (hasUserName) { - const atPosition = login.username.indexOf("@"); - if (atPosition > -1) { - userInput = userInput - .concat( - login.username - .substr(0, atPosition) - .trim() - .toLowerCase() - .split(/[^A-Za-z0-9]/), - ) - .filter((i) => i.length >= 3); - } else { - userInput = login.username - .trim() - .toLowerCase() - .split(/[^A-Za-z0-9]/) - .filter((i) => i.length >= 3); - } + if (index > -1) { + // update the existing cipher + this.weakPasswordCiphers[index] = updatedReportResult; + this.filterCiphersByOrg(this.weakPasswordCiphers); } - const result = this.passwordStrengthService.getPasswordStrength( - login.password, - null, - userInput.length > 0 ? userInput : null, - ); + } + } - if (result.score != null && result.score <= 2) { - const scoreValue = this.scoreKey(result.score); - const row = { - ...ciph, - score: result.score, - reportValue: scoreValue, - scoreKey: scoreValue.sortOrder, - } as ReportResult; + protected findWeakPasswords(ciphers: CipherView[]): void { + ciphers.forEach((ciph) => { + const row = this.determineWeakPasswordScore(ciph); + if (row != null) { this.weakPasswordCiphers.push(row); } }); this.filterCiphersByOrg(this.weakPasswordCiphers); } + protected determineWeakPasswordScore(ciph: CipherView): ReportResult | null { + const { type, login, isDeleted, edit, viewPassword } = ciph; + if ( + type !== CipherType.Login || + login.password == null || + login.password === "" || + isDeleted || + (!this.organization && !edit) || + !viewPassword + ) { + return; + } + + const hasUserName = this.isUserNameNotEmpty(ciph); + let userInput: string[] = []; + if (hasUserName) { + const atPosition = login.username.indexOf("@"); + if (atPosition > -1) { + userInput = userInput + .concat( + login.username + .substr(0, atPosition) + .trim() + .toLowerCase() + .split(/[^A-Za-z0-9]/), + ) + .filter((i) => i.length >= 3); + } else { + userInput = login.username + .trim() + .toLowerCase() + .split(/[^A-Za-z0-9]/) + .filter((i) => i.length >= 3); + } + } + const result = this.passwordStrengthService.getPasswordStrength( + login.password, + null, + userInput.length > 0 ? userInput : null, + ); + + if (result.score != null && result.score <= 2) { + const scoreValue = this.scoreKey(result.score); + return { + ...ciph, + score: result.score, + reportValue: scoreValue, + scoreKey: scoreValue.sortOrder, + } as ReportResult; + } + + return null; + } + protected canManageCipher(c: CipherView): boolean { // this will only ever be false from the org view; return true; diff --git a/apps/web/src/app/vault/org-vault/services/admin-console-cipher-form-config.service.ts b/apps/web/src/app/vault/org-vault/services/admin-console-cipher-form-config.service.ts index dd9cef91a54..15af27ba8d0 100644 --- a/apps/web/src/app/vault/org-vault/services/admin-console-cipher-form-config.service.ts +++ b/apps/web/src/app/vault/org-vault/services/admin-console-cipher-form-config.service.ts @@ -100,7 +100,7 @@ export class AdminConsoleCipherFormConfigService implements CipherFormConfigServ }; } - private async getCipher(id: CipherId | null, organization: Organization): Promise { + async getCipher(id: CipherId | null, organization: Organization): Promise { if (id == null) { return null; } From abf7c949d98e9213cf37ae7339b9ab88031bb6ef Mon Sep 17 00:00:00 2001 From: Oscar Hinton Date: Thu, 1 May 2025 15:22:18 +0200 Subject: [PATCH 09/19] Move additional linting to architecture (#14580) --- .github/renovate.json5 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index ee97f16b0a9..91b4ac86328 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -149,6 +149,8 @@ { matchPackageNames: [ "@angular-eslint/schematics", + "@typescript-eslint/rule-tester", + "@typescript-eslint/utils", "angular-eslint", "eslint-config-prettier", "eslint-import-resolver-typescript", @@ -313,8 +315,6 @@ "@storybook/angular", "@storybook/manager-api", "@storybook/theming", - "@typescript-eslint/utils", - "@typescript-eslint/rule-tester", "@types/react", "autoprefixer", "bootstrap", From 1d004950785d9b003fd475a7e3e7f2c0f1e22640 Mon Sep 17 00:00:00 2001 From: Justin Baur <19896123+justindbaur@users.noreply.github.com> Date: Thu, 1 May 2025 09:32:10 -0400 Subject: [PATCH 10/19] [PM-20032] Give option to skip token refresh on `fullSync` (#14423) * Give option to skip token refresh on fullSync * Fix listener --- .../sync/foreground-sync.service.spec.ts | 78 ++++++- .../platform/sync/foreground-sync.service.ts | 20 +- .../sync/sync-service.listener.spec.ts | 22 +- .../platform/sync/sync-service.listener.ts | 9 +- .../src/platform/sync/core-sync.service.ts | 3 + .../sync/default-sync.service.spec.ts | 199 ++++++++++++++++++ .../src/platform/sync/default-sync.service.ts | 15 +- libs/common/src/platform/sync/sync.service.ts | 29 ++- 8 files changed, 355 insertions(+), 20 deletions(-) create mode 100644 libs/common/src/platform/sync/default-sync.service.spec.ts diff --git a/apps/browser/src/platform/sync/foreground-sync.service.spec.ts b/apps/browser/src/platform/sync/foreground-sync.service.spec.ts index f5daff93815..34ee4fa0f77 100644 --- a/apps/browser/src/platform/sync/foreground-sync.service.spec.ts +++ b/apps/browser/src/platform/sync/foreground-sync.service.spec.ts @@ -8,6 +8,7 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { MessageListener, MessageSender } from "@bitwarden/common/platform/messaging"; import { Utils } from "@bitwarden/common/platform/misc/utils"; +import { SyncOptions } from "@bitwarden/common/platform/sync/sync.service"; import { FakeStateProvider, mockAccountServiceWith } from "@bitwarden/common/spec"; import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.service.abstraction"; import { InternalSendService } from "@bitwarden/common/tools/send/services/send.service.abstraction"; @@ -80,7 +81,72 @@ describe("ForegroundSyncService", () => { const fullSyncPromise = sut.fullSync(true, false); expect(sut.syncInProgress).toBe(true); - const requestId = getAndAssertRequestId({ forceSync: true, allowThrowOnError: false }); + const requestId = getAndAssertRequestId({ + forceSync: true, + options: { allowThrowOnError: false, skipTokenRefresh: false }, + }); + + // Pretend the sync has finished + messages.next({ successfully: true, errorMessage: null, requestId: requestId }); + + const result = await fullSyncPromise; + + expect(sut.syncInProgress).toBe(false); + expect(result).toBe(true); + }); + + const testData: { + input: boolean | SyncOptions | undefined; + normalized: Required; + }[] = [ + { + input: undefined, + normalized: { allowThrowOnError: false, skipTokenRefresh: false }, + }, + { + input: true, + normalized: { allowThrowOnError: true, skipTokenRefresh: false }, + }, + { + input: false, + normalized: { allowThrowOnError: false, skipTokenRefresh: false }, + }, + { + input: { allowThrowOnError: false }, + normalized: { allowThrowOnError: false, skipTokenRefresh: false }, + }, + { + input: { allowThrowOnError: true }, + normalized: { allowThrowOnError: true, skipTokenRefresh: false }, + }, + { + input: { allowThrowOnError: false, skipTokenRefresh: false }, + normalized: { allowThrowOnError: false, skipTokenRefresh: false }, + }, + { + input: { allowThrowOnError: true, skipTokenRefresh: false }, + normalized: { allowThrowOnError: true, skipTokenRefresh: false }, + }, + { + input: { allowThrowOnError: true, skipTokenRefresh: true }, + normalized: { allowThrowOnError: true, skipTokenRefresh: true }, + }, + { + input: { allowThrowOnError: false, skipTokenRefresh: true }, + normalized: { allowThrowOnError: false, skipTokenRefresh: true }, + }, + ]; + + it.each(testData)("normalize input $input options correctly", async ({ input, normalized }) => { + const messages = new Subject(); + messageListener.messages$.mockReturnValue(messages); + const fullSyncPromise = sut.fullSync(true, input); + expect(sut.syncInProgress).toBe(true); + + const requestId = getAndAssertRequestId({ + forceSync: true, + options: normalized, + }); // Pretend the sync has finished messages.next({ successfully: true, errorMessage: null, requestId: requestId }); @@ -97,7 +163,10 @@ describe("ForegroundSyncService", () => { const fullSyncPromise = sut.fullSync(false, false); expect(sut.syncInProgress).toBe(true); - const requestId = getAndAssertRequestId({ forceSync: false, allowThrowOnError: false }); + const requestId = getAndAssertRequestId({ + forceSync: false, + options: { allowThrowOnError: false, skipTokenRefresh: false }, + }); // Pretend the sync has finished messages.next({ @@ -118,7 +187,10 @@ describe("ForegroundSyncService", () => { const fullSyncPromise = sut.fullSync(true, true); expect(sut.syncInProgress).toBe(true); - const requestId = getAndAssertRequestId({ forceSync: true, allowThrowOnError: true }); + const requestId = getAndAssertRequestId({ + forceSync: true, + options: { allowThrowOnError: true, skipTokenRefresh: false }, + }); // Pretend the sync has finished messages.next({ diff --git a/apps/browser/src/platform/sync/foreground-sync.service.ts b/apps/browser/src/platform/sync/foreground-sync.service.ts index a6ed7281851..ce776f53685 100644 --- a/apps/browser/src/platform/sync/foreground-sync.service.ts +++ b/apps/browser/src/platform/sync/foreground-sync.service.ts @@ -14,6 +14,7 @@ import { import { Utils } from "@bitwarden/common/platform/misc/utils"; import { StateProvider } from "@bitwarden/common/platform/state"; import { CoreSyncService } from "@bitwarden/common/platform/sync/internal"; +import { SyncOptions } from "@bitwarden/common/platform/sync/sync.service"; import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.service.abstraction"; import { InternalSendService } from "@bitwarden/common/tools/send/services/send.service.abstraction"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; @@ -22,7 +23,7 @@ import { InternalFolderService } from "@bitwarden/common/vault/abstractions/fold import { FULL_SYNC_FINISHED } from "./sync-service.listener"; -export type FullSyncMessage = { forceSync: boolean; allowThrowOnError: boolean; requestId: string }; +export type FullSyncMessage = { forceSync: boolean; options: SyncOptions; requestId: string }; export const DO_FULL_SYNC = new CommandDefinition("doFullSync"); @@ -60,9 +61,20 @@ export class ForegroundSyncService extends CoreSyncService { ); } - async fullSync(forceSync: boolean, allowThrowOnError: boolean = false): Promise { + async fullSync( + forceSync: boolean, + allowThrowOnErrorOrOptions?: boolean | SyncOptions, + ): Promise { this.syncInProgress = true; try { + // Normalize options + const options = + typeof allowThrowOnErrorOrOptions === "boolean" + ? { allowThrowOnError: allowThrowOnErrorOrOptions, skipTokenRefresh: false } + : { + allowThrowOnError: allowThrowOnErrorOrOptions?.allowThrowOnError ?? false, + skipTokenRefresh: allowThrowOnErrorOrOptions?.skipTokenRefresh ?? false, + }; const requestId = Utils.newGuid(); const syncCompletedPromise = firstValueFrom( this.messageListener.messages$(FULL_SYNC_FINISHED).pipe( @@ -79,10 +91,10 @@ export class ForegroundSyncService extends CoreSyncService { }), ), ); - this.messageSender.send(DO_FULL_SYNC, { forceSync, allowThrowOnError, requestId }); + this.messageSender.send(DO_FULL_SYNC, { forceSync, options, requestId }); const result = await syncCompletedPromise; - if (allowThrowOnError && result.errorMessage != null) { + if (options.allowThrowOnError && result.errorMessage != null) { throw new Error(result.errorMessage); } diff --git a/apps/browser/src/platform/sync/sync-service.listener.spec.ts b/apps/browser/src/platform/sync/sync-service.listener.spec.ts index 51f97e9f879..9682e2cdb57 100644 --- a/apps/browser/src/platform/sync/sync-service.listener.spec.ts +++ b/apps/browser/src/platform/sync/sync-service.listener.spec.ts @@ -27,11 +27,18 @@ describe("SyncServiceListener", () => { const emissionPromise = firstValueFrom(listener); syncService.fullSync.mockResolvedValueOnce(value); - messages.next({ forceSync: true, allowThrowOnError: false, requestId: "1" }); + messages.next({ + forceSync: true, + options: { allowThrowOnError: false, skipTokenRefresh: false }, + requestId: "1", + }); await emissionPromise; - expect(syncService.fullSync).toHaveBeenCalledWith(true, false); + expect(syncService.fullSync).toHaveBeenCalledWith(true, { + allowThrowOnError: false, + skipTokenRefresh: false, + }); expect(messageSender.send).toHaveBeenCalledWith(FULL_SYNC_FINISHED, { successfully: value, errorMessage: null, @@ -45,11 +52,18 @@ describe("SyncServiceListener", () => { const emissionPromise = firstValueFrom(listener); syncService.fullSync.mockRejectedValueOnce(new Error("SyncError")); - messages.next({ forceSync: true, allowThrowOnError: false, requestId: "1" }); + messages.next({ + forceSync: true, + options: { allowThrowOnError: false, skipTokenRefresh: false }, + requestId: "1", + }); await emissionPromise; - expect(syncService.fullSync).toHaveBeenCalledWith(true, false); + expect(syncService.fullSync).toHaveBeenCalledWith(true, { + allowThrowOnError: false, + skipTokenRefresh: false, + }); expect(messageSender.send).toHaveBeenCalledWith(FULL_SYNC_FINISHED, { successfully: false, errorMessage: "SyncError", diff --git a/apps/browser/src/platform/sync/sync-service.listener.ts b/apps/browser/src/platform/sync/sync-service.listener.ts index b7171528648..4274eafcf6a 100644 --- a/apps/browser/src/platform/sync/sync-service.listener.ts +++ b/apps/browser/src/platform/sync/sync-service.listener.ts @@ -9,6 +9,7 @@ import { MessageSender, isExternalMessage, } from "@bitwarden/common/platform/messaging"; +import { SyncOptions } from "@bitwarden/common/platform/sync/sync.service"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { DO_FULL_SYNC } from "./foreground-sync.service"; @@ -34,15 +35,15 @@ export class SyncServiceListener { listener$(): Observable { return this.messageListener.messages$(DO_FULL_SYNC).pipe( filter((message) => isExternalMessage(message)), - concatMap(async ({ forceSync, allowThrowOnError, requestId }) => { - await this.doFullSync(forceSync, allowThrowOnError, requestId); + concatMap(async ({ forceSync, options, requestId }) => { + await this.doFullSync(forceSync, options, requestId); }), ); } - private async doFullSync(forceSync: boolean, allowThrowOnError: boolean, requestId: string) { + private async doFullSync(forceSync: boolean, options: SyncOptions, requestId: string) { try { - const result = await this.syncService.fullSync(forceSync, allowThrowOnError); + const result = await this.syncService.fullSync(forceSync, options); this.messageSender.send(FULL_SYNC_FINISHED, { successfully: result, errorMessage: null, diff --git a/libs/common/src/platform/sync/core-sync.service.ts b/libs/common/src/platform/sync/core-sync.service.ts index 1865ffb852f..4020c75f764 100644 --- a/libs/common/src/platform/sync/core-sync.service.ts +++ b/libs/common/src/platform/sync/core-sync.service.ts @@ -28,6 +28,8 @@ import { StateService } from "../abstractions/state.service"; import { MessageSender } from "../messaging"; import { StateProvider, SYNC_DISK, UserKeyDefinition } from "../state"; +import { SyncOptions } from "./sync.service"; + const LAST_SYNC_DATE = new UserKeyDefinition(SYNC_DISK, "lastSync", { deserializer: (d) => (d != null ? new Date(d) : null), clearOn: ["logout"], @@ -55,6 +57,7 @@ export abstract class CoreSyncService implements SyncService { protected readonly stateProvider: StateProvider, ) {} + abstract fullSync(forceSync: boolean, syncOptions?: SyncOptions): Promise; abstract fullSync(forceSync: boolean, allowThrowOnError?: boolean): Promise; async getLastSync(): Promise { diff --git a/libs/common/src/platform/sync/default-sync.service.spec.ts b/libs/common/src/platform/sync/default-sync.service.spec.ts new file mode 100644 index 00000000000..ded06c8be6b --- /dev/null +++ b/libs/common/src/platform/sync/default-sync.service.spec.ts @@ -0,0 +1,199 @@ +import { mock, MockProxy } from "jest-mock-extended"; +import { of } from "rxjs"; + +import { CollectionService } from "@bitwarden/admin-console/common"; +import { + LogoutReason, + UserDecryptionOptions, + UserDecryptionOptionsServiceAbstraction, +} from "@bitwarden/auth/common"; +import { KeyService } from "@bitwarden/key-management"; + +import { Matrix } from "../../../spec/matrix"; +import { ApiService } from "../../abstractions/api.service"; +import { InternalOrganizationServiceAbstraction } from "../../admin-console/abstractions/organization/organization.service.abstraction"; +import { InternalPolicyService } from "../../admin-console/abstractions/policy/policy.service.abstraction"; +import { ProviderService } from "../../admin-console/abstractions/provider.service"; +import { Account, AccountService } from "../../auth/abstractions/account.service"; +import { AuthService } from "../../auth/abstractions/auth.service"; +import { AvatarService } from "../../auth/abstractions/avatar.service"; +import { TokenService } from "../../auth/abstractions/token.service"; +import { AuthenticationStatus } from "../../auth/enums/authentication-status"; +import { DomainSettingsService } from "../../autofill/services/domain-settings.service"; +import { BillingAccountProfileStateService } from "../../billing/abstractions"; +import { KeyConnectorService } from "../../key-management/key-connector/abstractions/key-connector.service"; +import { InternalMasterPasswordServiceAbstraction } from "../../key-management/master-password/abstractions/master-password.service.abstraction"; +import { SendApiService } from "../../tools/send/services/send-api.service.abstraction"; +import { InternalSendService } from "../../tools/send/services/send.service.abstraction"; +import { UserId } from "../../types/guid"; +import { CipherService } from "../../vault/abstractions/cipher.service"; +import { FolderApiServiceAbstraction } from "../../vault/abstractions/folder/folder-api.service.abstraction"; +import { InternalFolderService } from "../../vault/abstractions/folder/folder.service.abstraction"; +import { LogService } from "../abstractions/log.service"; +import { StateService } from "../abstractions/state.service"; +import { MessageSender } from "../messaging"; +import { StateProvider } from "../state"; + +import { DefaultSyncService } from "./default-sync.service"; +import { SyncResponse } from "./sync.response"; + +describe("DefaultSyncService", () => { + let masterPasswordAbstraction: MockProxy; + let accountService: MockProxy; + let apiService: MockProxy; + let domainSettingsService: MockProxy; + let folderService: MockProxy; + let cipherService: MockProxy; + let keyService: MockProxy; + let collectionService: MockProxy; + let messageSender: MockProxy; + let policyService: MockProxy; + let sendService: MockProxy; + let logService: MockProxy; + let keyConnectorService: MockProxy; + let stateService: MockProxy; + let providerService: MockProxy; + let folderApiService: MockProxy; + let organizationService: MockProxy; + let sendApiService: MockProxy; + let userDecryptionOptionsService: MockProxy; + let avatarService: MockProxy; + let logoutCallback: jest.Mock, [logoutReason: LogoutReason, userId?: UserId]>; + let billingAccountProfileStateService: MockProxy; + let tokenService: MockProxy; + let authService: MockProxy; + let stateProvider: MockProxy; + + let sut: DefaultSyncService; + + beforeEach(() => { + masterPasswordAbstraction = mock(); + accountService = mock(); + apiService = mock(); + domainSettingsService = mock(); + folderService = mock(); + cipherService = mock(); + keyService = mock(); + collectionService = mock(); + messageSender = mock(); + policyService = mock(); + sendService = mock(); + logService = mock(); + keyConnectorService = mock(); + stateService = mock(); + providerService = mock(); + folderApiService = mock(); + organizationService = mock(); + sendApiService = mock(); + userDecryptionOptionsService = mock(); + avatarService = mock(); + logoutCallback = jest.fn(); + billingAccountProfileStateService = mock(); + tokenService = mock(); + authService = mock(); + stateProvider = mock(); + + sut = new DefaultSyncService( + masterPasswordAbstraction, + accountService, + apiService, + domainSettingsService, + folderService, + cipherService, + keyService, + collectionService, + messageSender, + policyService, + sendService, + logService, + keyConnectorService, + stateService, + providerService, + folderApiService, + organizationService, + sendApiService, + userDecryptionOptionsService, + avatarService, + logoutCallback, + billingAccountProfileStateService, + tokenService, + authService, + stateProvider, + ); + }); + + const user1 = "user1" as UserId; + + describe("fullSync", () => { + beforeEach(() => { + accountService.activeAccount$ = of({ id: user1 } as Account); + Matrix.autoMockMethod(authService.authStatusFor$, () => of(AuthenticationStatus.Unlocked)); + apiService.getSync.mockResolvedValue( + new SyncResponse({ + profile: { + id: user1, + }, + folders: [], + collections: [], + ciphers: [], + sends: [], + domains: [], + policies: [], + }), + ); + Matrix.autoMockMethod(userDecryptionOptionsService.userDecryptionOptionsById$, () => + of({ hasMasterPassword: true } satisfies UserDecryptionOptions), + ); + stateProvider.getUser.mockReturnValue(mock()); + }); + + it("does a token refresh when option missing from options", async () => { + await sut.fullSync(true, { allowThrowOnError: false }); + + expect(apiService.refreshIdentityToken).toHaveBeenCalledTimes(1); + expect(apiService.getSync).toHaveBeenCalledTimes(1); + }); + + it("does a token refresh when boolean passed in", async () => { + await sut.fullSync(true, false); + + expect(apiService.refreshIdentityToken).toHaveBeenCalledTimes(1); + expect(apiService.getSync).toHaveBeenCalledTimes(1); + }); + + it("does a token refresh when skipTokenRefresh option passed in with false and allowThrowOnError also passed in", async () => { + await sut.fullSync(true, { allowThrowOnError: false, skipTokenRefresh: false }); + + expect(apiService.refreshIdentityToken).toHaveBeenCalledTimes(1); + expect(apiService.getSync).toHaveBeenCalledTimes(1); + }); + + it("does a token refresh when skipTokenRefresh option passed in with false by itself", async () => { + await sut.fullSync(true, { skipTokenRefresh: false }); + + expect(apiService.refreshIdentityToken).toHaveBeenCalledTimes(1); + expect(apiService.getSync).toHaveBeenCalledTimes(1); + }); + + it("does not do a token refresh when skipTokenRefresh passed in as true", async () => { + await sut.fullSync(true, { skipTokenRefresh: true }); + + expect(apiService.refreshIdentityToken).not.toHaveBeenCalled(); + expect(apiService.getSync).toHaveBeenCalledTimes(1); + }); + + it("does not do a token refresh when skipTokenRefresh passed in as true and allowThrowOnError also passed in", async () => { + await sut.fullSync(true, { allowThrowOnError: false, skipTokenRefresh: true }); + + expect(apiService.refreshIdentityToken).not.toHaveBeenCalled(); + expect(apiService.getSync).toHaveBeenCalledTimes(1); + }); + + it("does a token refresh when nothing passed in", async () => { + await sut.fullSync(true); + + expect(apiService.refreshIdentityToken).toHaveBeenCalledTimes(1); + expect(apiService.getSync).toHaveBeenCalledTimes(1); + }); + }); +}); diff --git a/libs/common/src/platform/sync/default-sync.service.ts b/libs/common/src/platform/sync/default-sync.service.ts index a6b1b974645..faf54f11912 100644 --- a/libs/common/src/platform/sync/default-sync.service.ts +++ b/libs/common/src/platform/sync/default-sync.service.ts @@ -54,6 +54,7 @@ import { MessageSender } from "../messaging"; import { StateProvider } from "../state"; import { CoreSyncService } from "./core-sync.service"; +import { SyncOptions } from "./sync.service"; export class DefaultSyncService extends CoreSyncService { syncInProgress = false; @@ -102,7 +103,15 @@ export class DefaultSyncService extends CoreSyncService { ); } - override async fullSync(forceSync: boolean, allowThrowOnError = false): Promise { + override async fullSync( + forceSync: boolean, + allowThrowOnErrorOrOptions?: boolean | SyncOptions, + ): Promise { + const { allowThrowOnError = false, skipTokenRefresh = false } = + typeof allowThrowOnErrorOrOptions === "boolean" + ? { allowThrowOnError: allowThrowOnErrorOrOptions } + : (allowThrowOnErrorOrOptions ?? {}); + const userId = await firstValueFrom(this.accountService.activeAccount$.pipe(map((a) => a?.id))); this.syncStarted(); const authStatus = await firstValueFrom(this.authService.authStatusFor$(userId)); @@ -127,7 +136,9 @@ export class DefaultSyncService extends CoreSyncService { } try { - await this.apiService.refreshIdentityToken(); + if (!skipTokenRefresh) { + await this.apiService.refreshIdentityToken(); + } const response = await this.apiService.getSync(); await this.syncProfile(response.profile); diff --git a/libs/common/src/platform/sync/sync.service.ts b/libs/common/src/platform/sync/sync.service.ts index 967e4db27a5..6ef62fc9cb8 100644 --- a/libs/common/src/platform/sync/sync.service.ts +++ b/libs/common/src/platform/sync/sync.service.ts @@ -7,6 +7,26 @@ import { } from "../../models/response/notification.response"; import { UserId } from "../../types/guid"; +/** + * A set of options for configuring how a {@link SyncService.fullSync} call should behave. + */ +export type SyncOptions = { + /** + * A boolean dictating whether or not caught errors should be rethrown. + * `true` if they can be rethrown, `false` if they should not be rethrown. + * @default false + */ + allowThrowOnError?: boolean; + /** + * A boolean dictating whether or not to do a token refresh before doing the sync. + * `true` if the refresh can be skipped, likely because one was done soon before the call to + * `fullSync`. `false` if the token refresh should be done before getting data. + * + * @default false + */ + skipTokenRefresh?: boolean; +}; + /** * A class encapsulating sync operations and data. */ @@ -47,9 +67,12 @@ export abstract class SyncService { * as long as the current user is authenticated. If `false` it will only sync if either a sync * has not happened before or the last sync date for the active user is before their account * revision date. Try to always use `false` if possible. - * - * @param allowThrowOnError A boolean dictating whether or not caught errors should be rethrown. - * `true` if they can be rethrown, `false` if they should not be rethrown. + * @param syncOptions Options for customizing how the sync call should behave. + */ + abstract fullSync(forceSync: boolean, syncOptions?: SyncOptions): Promise; + + /** + * @deprecated Use the overload taking {@link SyncOptions} instead. */ abstract fullSync(forceSync: boolean, allowThrowOnError?: boolean): Promise; From 8090586b52006078250397916e67b9ad32526181 Mon Sep 17 00:00:00 2001 From: Matt Bishop Date: Thu, 1 May 2025 07:18:09 -0700 Subject: [PATCH 11/19] Fix some references to master (#14578) * Fix some references to master * Fix broken links --- LICENSE.txt | 6 +++--- LICENSE_BITWARDEN.txt | 2 +- apps/browser/README.md | 4 ++-- apps/cli/README.md | 2 +- apps/desktop/README.md | 2 +- apps/web/README.md | 6 +++--- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index 55bf3b3f736..8ad59f788b3 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -5,13 +5,13 @@ specifies another license. Bitwarden Licensed code is found only in the /bitwarden_license directory. GPL v3.0: -https://github.com/bitwarden/web/blob/master/LICENSE_GPL.txt +https://github.com/bitwarden/clients/blob/main/LICENSE_GPL.txt Bitwarden License v1.0: -https://github.com/bitwarden/web/blob/master/LICENSE_BITWARDEN.txt +https://github.com/bitwarden/clients/blob/main/LICENSE_BITWARDEN.txt No grant of any rights in the trademarks, service marks, or logos of Bitwarden is made (except as may be necessary to comply with the notice requirements as applicable), and use of any Bitwarden trademarks must comply with Bitwarden Trademark Guidelines -. +. diff --git a/LICENSE_BITWARDEN.txt b/LICENSE_BITWARDEN.txt index 08e09f28639..938946a09a1 100644 --- a/LICENSE_BITWARDEN.txt +++ b/LICENSE_BITWARDEN.txt @@ -56,7 +56,7 @@ such Open Source Software only. logos of any Contributor (except as may be necessary to comply with the notice requirements in Section 2.3), and use of any Bitwarden trademarks must comply with Bitwarden Trademark Guidelines -. +. 3. TERMINATION diff --git a/apps/browser/README.md b/apps/browser/README.md index c99d0844a09..fdeb1307567 100644 --- a/apps/browser/README.md +++ b/apps/browser/README.md @@ -1,4 +1,4 @@ -[![Github Workflow build browser on master](https://github.com/bitwarden/clients/actions/workflows/build-browser.yml/badge.svg?branch=master)](https://github.com/bitwarden/clients/actions/workflows/build-browser.yml?query=branch:master) +[![Github Workflow build browser on main](https://github.com/bitwarden/clients/actions/workflows/build-browser.yml/badge.svg?branch=main)](https://github.com/bitwarden/clients/actions/workflows/build-browser.yml?query=branch:main) [![Crowdin](https://d322cqt584bo4o.cloudfront.net/bitwarden-browser/localized.svg)](https://crowdin.com/project/bitwarden-browser) [![Join the chat at https://gitter.im/bitwarden/Lobby](https://badges.gitter.im/bitwarden/Lobby.svg)](https://gitter.im/bitwarden/Lobby) @@ -15,7 +15,7 @@ The Bitwarden browser extension is written using the Web Extension API and Angular. -![My Vault](https://raw.githubusercontent.com/bitwarden/brand/master/screenshots/browser-chrome.png) +![My Vault](https://raw.githubusercontent.com/bitwarden/brand/main/screenshots/web-browser-extension-generator.png) ## Documentation diff --git a/apps/cli/README.md b/apps/cli/README.md index d39c0e39c8f..2b13270cdba 100644 --- a/apps/cli/README.md +++ b/apps/cli/README.md @@ -1,4 +1,4 @@ -[![Github Workflow build on master](https://github.com/bitwarden/clients/actions/workflows/build-cli.yml/badge.svg?branch=master)](https://github.com/bitwarden/clients/actions/workflows/build-cli.yml?query=branch:master) +[![Github Workflow build on main](https://github.com/bitwarden/clients/actions/workflows/build-cli.yml/badge.svg?branch=main)](https://github.com/bitwarden/clients/actions/workflows/build-cli.yml?query=branch:main) [![Join the chat at https://gitter.im/bitwarden/Lobby](https://badges.gitter.im/bitwarden/Lobby.svg)](https://gitter.im/bitwarden/Lobby) # Bitwarden Command-line Interface diff --git a/apps/desktop/README.md b/apps/desktop/README.md index 6578699369b..ee13f451641 100644 --- a/apps/desktop/README.md +++ b/apps/desktop/README.md @@ -1,4 +1,4 @@ -[![Github Workflow build on master](https://github.com/bitwarden/clients/actions/workflows/build-desktop.yml/badge.svg?branch=master)](https://github.com/bitwarden/clients/actions/workflows/build-desktop.yml?query=branch:master) +[![Github Workflow build on main](https://github.com/bitwarden/clients/actions/workflows/build-desktop.yml/badge.svg?branch=main)](https://github.com/bitwarden/clients/actions/workflows/build-desktop.yml?query=branch:main) [![Crowdin](https://d322cqt584bo4o.cloudfront.net/bitwarden-desktop/localized.svg)](https://crowdin.com/project/bitwarden-desktop) [![Join the chat at https://gitter.im/bitwarden/Lobby](https://badges.gitter.im/bitwarden/Lobby.svg)](https://gitter.im/bitwarden/Lobby) diff --git a/apps/web/README.md b/apps/web/README.md index f43a9dc1614..c5e03eebb59 100644 --- a/apps/web/README.md +++ b/apps/web/README.md @@ -1,12 +1,12 @@

- +

The Bitwarden web project is an Angular application that powers the web vault (https://vault.bitwarden.com/).

- - Github Workflow build on master + + Github Workflow build on main Crowdin From 1b66f0f06b449444a0f81522c1fe8a28d998d88c Mon Sep 17 00:00:00 2001 From: Github Actions Date: Thu, 1 May 2025 14:22:26 +0000 Subject: [PATCH 12/19] Bumped Desktop client to 2025.5.0 --- apps/desktop/package.json | 2 +- apps/desktop/src/package-lock.json | 4 ++-- apps/desktop/src/package.json | 2 +- package-lock.json | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/desktop/package.json b/apps/desktop/package.json index e00df0b26df..21892cd1df8 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -1,7 +1,7 @@ { "name": "@bitwarden/desktop", "description": "A secure and free password manager for all of your devices.", - "version": "2025.4.2", + "version": "2025.5.0", "keywords": [ "bitwarden", "password", diff --git a/apps/desktop/src/package-lock.json b/apps/desktop/src/package-lock.json index f6449bd9626..b3a33dc75e3 100644 --- a/apps/desktop/src/package-lock.json +++ b/apps/desktop/src/package-lock.json @@ -1,12 +1,12 @@ { "name": "@bitwarden/desktop", - "version": "2025.4.2", + "version": "2025.5.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@bitwarden/desktop", - "version": "2025.4.2", + "version": "2025.5.0", "license": "GPL-3.0", "dependencies": { "@bitwarden/desktop-napi": "file:../desktop_native/napi" diff --git a/apps/desktop/src/package.json b/apps/desktop/src/package.json index 45a6f6b90af..c180ed8c744 100644 --- a/apps/desktop/src/package.json +++ b/apps/desktop/src/package.json @@ -2,7 +2,7 @@ "name": "@bitwarden/desktop", "productName": "Bitwarden", "description": "A secure and free password manager for all of your devices.", - "version": "2025.4.2", + "version": "2025.5.0", "author": "Bitwarden Inc. (https://bitwarden.com)", "homepage": "https://bitwarden.com", "license": "GPL-3.0", diff --git a/package-lock.json b/package-lock.json index 671951c0349..25322b844b7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -231,7 +231,7 @@ }, "apps/desktop": { "name": "@bitwarden/desktop", - "version": "2025.4.2", + "version": "2025.5.0", "hasInstallScript": true, "license": "GPL-3.0" }, From a7d04dc21276c5152ca6ab5d6f55159ec356c4c5 Mon Sep 17 00:00:00 2001 From: cyprain-okeke <108260115+cyprain-okeke@users.noreply.github.com> Date: Thu, 1 May 2025 16:36:00 +0100 Subject: [PATCH 13/19] [PM-17775] Allow admin to send f4 e sponsorship (#14390) * Added nav item for f4e in org admin console * shotgun surgery for adding "useAdminSponsoredFamilies" feature from the org table * Resolved issue with members nav item also being selected when f4e is selected * Separated out billing's logic from the org layout component * Removed unused observable * Moved logic to existing f4e policy service and added unit tests * Resolved script typescript error * Resolved goofy switchMap * Add changes for the issue orgs * Added changes for the dialog * Rename the files properly * Remove the commented code * Change the implement to align with design * Add todo comments * Remove the comment todo * Fix the uni test error * Resolve the unit test * Resolve the unit test issue * Resolve the pr comments on any and route * remove the any * remove the generic validator * Resolve the unit test * add validations for email * Add changes for the autoscale * Changes to allow admin to send F4E sponsorship * Fix the lint errors * Resolve the lint errors * Fix the revokeAccount message * Fix the lint runtime error * Resolve the lint issues * Remove unused components * Changes to add isadminInitiated * remove the FIXME comment * Resolve the failing test * Fix the pr comments * Resolve the orgkey and other comments * Resolve the lint error * Resolve the lint error * resolve the spelling error * refactor the getStatus method * Remove the deprecated method * Resolve the unusual type casting * revert the change --------- Co-authored-by: Conner Turnbull Co-authored-by: Conner Turnbull <133619638+cturnbull-bitwarden@users.noreply.github.com> --- .../add-sponsorship-dialog.component.html | 10 +- .../add-sponsorship-dialog.component.ts | 131 +++++---- .../free-bitwarden-families.component.html | 104 ++++++- .../free-bitwarden-families.component.ts | 261 +++++++++++++++--- ...rganization-member-families.component.html | 47 ---- .../organization-member-families.component.ts | 34 --- ...nization-sponsored-families.component.html | 87 ------ ...ganization-sponsored-families.component.ts | 39 --- .../sponsored-families.component.html | 2 +- .../sponsoring-org-row.component.html | 2 +- .../src/app/shared/loose-components.module.ts | 6 - apps/web/src/locales/en/messages.json | 21 +- .../src/services/jslib-services.module.ts | 7 + ...organization-sponsorship-create.request.ts | 1 + ...ion-sponsorship-api.service.abstraction.ts | 8 + ...ganization-sponsorship-invites.response.ts | 31 +++ .../organization-sponsorship-api.service.ts | 22 ++ 17 files changed, 491 insertions(+), 322 deletions(-) delete mode 100644 apps/web/src/app/billing/members/organization-member-families.component.html delete mode 100644 apps/web/src/app/billing/members/organization-member-families.component.ts delete mode 100644 apps/web/src/app/billing/members/organization-sponsored-families.component.html delete mode 100644 apps/web/src/app/billing/members/organization-sponsored-families.component.ts create mode 100644 libs/common/src/billing/abstractions/organizations/organization-sponsorship-api.service.abstraction.ts create mode 100644 libs/common/src/billing/models/response/organization-sponsorship-invites.response.ts create mode 100644 libs/common/src/billing/services/organization/organization-sponsorship-api.service.ts diff --git a/apps/web/src/app/billing/members/add-sponsorship-dialog.component.html b/apps/web/src/app/billing/members/add-sponsorship-dialog.component.html index 2dbcc577e54..405211d6ecb 100644 --- a/apps/web/src/app/billing/members/add-sponsorship-dialog.component.html +++ b/apps/web/src/app/billing/members/add-sponsorship-dialog.component.html @@ -34,7 +34,15 @@

- - - - - + + +

+ {{ "sponsorshipFreeBitwardenFamilies" | i18n }} +

+
+ {{ "sponsoredFamiliesInclude" | i18n }}: +
    +
  • {{ "sponsoredFamiliesPremiumAccess" | i18n }}
  • +
  • {{ "sponsoredFamiliesSharedCollectionsMessage" | i18n }}
  • +
+
- - - -
+

{{ "sponsoredBitwardenFamilies" | i18n }}

-

{{ "sponsoredFamiliesRemoveActiveSponsorship" | i18n }}

+ @if (loading()) { + + + {{ "loading" | i18n }} + + } + + @if (!loading() && sponsoredFamilies?.length > 0) { + + + + + {{ "recipient" | i18n }} + {{ "status" | i18n }} + {{ "notes" | i18n }} + + + + + @for (o of sponsoredFamilies; let i = $index; track i) { + + + {{ o.friendlyName }} + {{ o.statusMessage }} + {{ o.notes }} + + + + + +
+ + +
+ + +
+ } +
+
+
+
+ } @else if (!loading()) { +
+ Search +

{{ "noSponsoredFamiliesMessage" | i18n }}

+

{{ "nosponsoredFamiliesDetails" | i18n }}

+
+ } + + @if (!loading() && sponsoredFamilies.length > 0) { +

{{ "sponsoredFamiliesRemoveActiveSponsorship" | i18n }}

+ } +
+ diff --git a/apps/web/src/app/billing/members/free-bitwarden-families.component.ts b/apps/web/src/app/billing/members/free-bitwarden-families.component.ts index af43e5a4bc1..c141eaebd78 100644 --- a/apps/web/src/app/billing/members/free-bitwarden-families.component.ts +++ b/apps/web/src/app/billing/members/free-bitwarden-families.component.ts @@ -1,62 +1,259 @@ import { DialogRef } from "@angular/cdk/dialog"; -import { Component, OnInit } from "@angular/core"; -import { Router } from "@angular/router"; -import { firstValueFrom } from "rxjs"; +import { formatDate } from "@angular/common"; +import { Component, OnInit, signal } from "@angular/core"; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { ActivatedRoute } from "@angular/router"; +import { firstValueFrom, map, Observable, switchMap } from "rxjs"; -import { DialogService } from "@bitwarden/components"; +import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { OrganizationSponsorshipApiServiceAbstraction } from "@bitwarden/common/billing/abstractions/organizations/organization-sponsorship-api.service.abstraction"; +import { OrganizationSponsorshipInvitesResponse } from "@bitwarden/common/billing/models/response/organization-sponsorship-invites.response"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; +import { StateProvider } from "@bitwarden/common/platform/state"; +import { OrganizationId, UserId } from "@bitwarden/common/types/guid"; +import { OrgKey } from "@bitwarden/common/types/key"; +import { DialogService, ToastService } from "@bitwarden/components"; +import { KeyService } from "@bitwarden/key-management"; -import { FreeFamiliesPolicyService } from "../services/free-families-policy.service"; - -import { - AddSponsorshipDialogComponent, - AddSponsorshipDialogResult, -} from "./add-sponsorship-dialog.component"; -import { SponsoredFamily } from "./types/sponsored-family"; +import { AddSponsorshipDialogComponent } from "./add-sponsorship-dialog.component"; @Component({ selector: "app-free-bitwarden-families", templateUrl: "free-bitwarden-families.component.html", }) export class FreeBitwardenFamiliesComponent implements OnInit { + loading = signal(true); tabIndex = 0; - sponsoredFamilies: SponsoredFamily[] = []; + sponsoredFamilies: OrganizationSponsorshipInvitesResponse[] = []; + + organizationId = ""; + organizationKey$: Observable; + + private locale: string = ""; constructor( - private router: Router, + private route: ActivatedRoute, private dialogService: DialogService, - private freeFamiliesPolicyService: FreeFamiliesPolicyService, - ) {} + private apiService: ApiService, + private encryptService: EncryptService, + private keyService: KeyService, + private platformUtilsService: PlatformUtilsService, + private i18nService: I18nService, + private logService: LogService, + private toastService: ToastService, + private organizationSponsorshipApiService: OrganizationSponsorshipApiServiceAbstraction, + private stateProvider: StateProvider, + ) { + this.organizationId = this.route.snapshot.params.organizationId || ""; + this.organizationKey$ = this.stateProvider.activeUserId$.pipe( + switchMap( + (userId) => + this.keyService.orgKeys$(userId as UserId) as Observable>, + ), + map((organizationKeysById) => organizationKeysById[this.organizationId as OrganizationId]), + takeUntilDestroyed(), + ); + } async ngOnInit() { - await this.preventAccessToFreeFamiliesPage(); + this.locale = await firstValueFrom(this.i18nService.locale$); + await this.loadSponsorships(); + + this.loading.set(false); + } + + async loadSponsorships() { + if (!this.organizationId) { + return; + } + + const [response, orgKey] = await Promise.all([ + this.organizationSponsorshipApiService.getOrganizationSponsorship(this.organizationId), + firstValueFrom(this.organizationKey$), + ]); + + if (!orgKey) { + this.logService.error("Organization key not found"); + return; + } + + const organizationFamilies = response.data; + + this.sponsoredFamilies = await Promise.all( + organizationFamilies.map(async (family) => { + let decryptedNote = ""; + try { + decryptedNote = await this.encryptService.decryptString( + new EncString(family.notes), + orgKey, + ); + } catch (e) { + this.logService.error(e); + } + + const { statusMessage, statusClass } = this.getStatus( + this.isSelfHosted, + family.toDelete, + family.validUntil, + family.lastSyncDate, + this.locale, + ); + + const newFamily = { + ...family, + notes: decryptedNote, + statusMessage: statusMessage || "", + statusClass: statusClass || "tw-text-success", + status: statusMessage || "", + }; + + return new OrganizationSponsorshipInvitesResponse(newFamily); + }), + ); } async addSponsorship() { - const addSponsorshipDialogRef: DialogRef = - AddSponsorshipDialogComponent.open(this.dialogService); + const addSponsorshipDialogRef: DialogRef = AddSponsorshipDialogComponent.open( + this.dialogService, + { + data: { + organizationId: this.organizationId, + organizationKey: await firstValueFrom(this.organizationKey$), + }, + }, + ); - const dialogRef = await firstValueFrom(addSponsorshipDialogRef.closed); + await firstValueFrom(addSponsorshipDialogRef.closed); - if (dialogRef?.value) { - this.sponsoredFamilies = [dialogRef.value, ...this.sponsoredFamilies]; + await this.loadSponsorships(); + } + + async removeSponsorship(sponsorship: OrganizationSponsorshipInvitesResponse) { + try { + await this.doRevokeSponsorship(sponsorship); + } catch (e) { + this.logService.error(e); } } - removeSponsorhip(sponsorship: any) { - const index = this.sponsoredFamilies.findIndex( - (e) => e.sponsorshipEmail == sponsorship.sponsorshipEmail, - ); - this.sponsoredFamilies.splice(index, 1); + get isSelfHosted(): boolean { + return this.platformUtilsService.isSelfHost(); } - private async preventAccessToFreeFamiliesPage() { - const showFreeFamiliesPage = await firstValueFrom( - this.freeFamiliesPolicyService.showFreeFamilies$, - ); + async resendEmail(sponsorship: OrganizationSponsorshipInvitesResponse) { + await this.apiService.postResendSponsorshipOffer(sponsorship.sponsoringOrganizationUserId); + this.toastService.showToast({ + variant: "success", + title: undefined, + message: this.i18nService.t("emailSent"), + }); + } - if (!showFreeFamiliesPage) { - await this.router.navigate(["/"]); + private async doRevokeSponsorship(sponsorship: OrganizationSponsorshipInvitesResponse) { + const content = sponsorship.validUntil + ? this.i18nService.t( + "updatedRevokeSponsorshipConfirmationForAcceptedSponsorship", + sponsorship.friendlyName, + formatDate(sponsorship.validUntil, "MM/dd/yyyy", this.locale), + ) + : this.i18nService.t( + "updatedRevokeSponsorshipConfirmationForSentSponsorship", + sponsorship.friendlyName, + ); + + const confirmed = await this.dialogService.openSimpleDialog({ + title: `${this.i18nService.t("removeSponsorship")}?`, + content, + acceptButtonText: { key: "remove" }, + type: "warning", + }); + + if (!confirmed) { return; } + + await this.apiService.deleteRevokeSponsorship(sponsorship.sponsoringOrganizationUserId); + + this.toastService.showToast({ + variant: "success", + title: undefined, + message: this.i18nService.t("reclaimedFreePlan"), + }); + + await this.loadSponsorships(); + } + + private getStatus( + selfHosted: boolean, + toDelete?: boolean, + validUntil?: Date, + lastSyncDate?: Date, + locale: string = "", + ): { statusMessage: string; statusClass: "tw-text-success" | "tw-text-danger" } { + /* + * Possible Statuses: + * Requested (self-hosted only) + * Sent + * Active + * RequestRevoke + * RevokeWhenExpired + */ + + if (toDelete && validUntil) { + // They want to delete but there is a valid until date which means there is an active sponsorship + return { + statusMessage: this.i18nService.t( + "revokeWhenExpired", + formatDate(validUntil, "MM/dd/yyyy", locale), + ), + statusClass: "tw-text-danger", + }; + } + + if (toDelete) { + // They want to delete and we don't have a valid until date so we can + // this should only happen on a self-hosted install + return { + statusMessage: this.i18nService.t("requestRemoved"), + statusClass: "tw-text-danger", + }; + } + + if (validUntil) { + // They don't want to delete and they have a valid until date + // that means they are actively sponsoring someone + return { + statusMessage: this.i18nService.t("active"), + statusClass: "tw-text-success", + }; + } + + if (selfHosted && lastSyncDate) { + // We are on a self-hosted install and it has been synced but we have not gotten + // a valid until date so we can't know if they are actively sponsoring someone + return { + statusMessage: this.i18nService.t("sent"), + statusClass: "tw-text-success", + }; + } + + if (!selfHosted) { + // We are in cloud and all other status checks have been false therefore we have + // sent the request but it hasn't been accepted yet + return { + statusMessage: this.i18nService.t("sent"), + statusClass: "tw-text-success", + }; + } + + // We are on a self-hosted install and we have not synced yet + return { + statusMessage: this.i18nService.t("requested"), + statusClass: "tw-text-success", + }; } } diff --git a/apps/web/src/app/billing/members/organization-member-families.component.html b/apps/web/src/app/billing/members/organization-member-families.component.html deleted file mode 100644 index c5b7283d9d9..00000000000 --- a/apps/web/src/app/billing/members/organization-member-families.component.html +++ /dev/null @@ -1,47 +0,0 @@ - - -

- {{ "membersWithSponsoredFamilies" | i18n }} -

- -

{{ "memberFamilies" | i18n }}

- - @if (loading) { - - - {{ "loading" | i18n }} - - } - - @if (!loading && memberFamilies?.length > 0) { - - - - - {{ "member" | i18n }} - {{ "status" | i18n }} - - - - - @for (o of memberFamilies; let i = $index; track i) { - - - {{ o.sponsorshipEmail }} - {{ o.status }} - - - } - - -
-
- } @else { -
- Search -

{{ "noMemberFamilies" | i18n }}

-

{{ "noMemberFamiliesDescription" | i18n }}

-
- } -
-
diff --git a/apps/web/src/app/billing/members/organization-member-families.component.ts b/apps/web/src/app/billing/members/organization-member-families.component.ts deleted file mode 100644 index 52c95646a11..00000000000 --- a/apps/web/src/app/billing/members/organization-member-families.component.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Component, Input, OnDestroy, OnInit } from "@angular/core"; -import { Subject } from "rxjs"; - -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; - -import { SponsoredFamily } from "./types/sponsored-family"; - -@Component({ - selector: "app-organization-member-families", - templateUrl: "organization-member-families.component.html", -}) -export class OrganizationMemberFamiliesComponent implements OnInit, OnDestroy { - tabIndex = 0; - loading = false; - - @Input() memberFamilies: SponsoredFamily[] = []; - - private _destroy = new Subject(); - - constructor(private platformUtilsService: PlatformUtilsService) {} - - async ngOnInit() { - this.loading = false; - } - - ngOnDestroy(): void { - this._destroy.next(); - this._destroy.complete(); - } - - get isSelfHosted(): boolean { - return this.platformUtilsService.isSelfHost(); - } -} diff --git a/apps/web/src/app/billing/members/organization-sponsored-families.component.html b/apps/web/src/app/billing/members/organization-sponsored-families.component.html deleted file mode 100644 index 7db96deb4ab..00000000000 --- a/apps/web/src/app/billing/members/organization-sponsored-families.component.html +++ /dev/null @@ -1,87 +0,0 @@ - - -

- {{ "sponsorFreeBitwardenFamilies" | i18n }} -

-
- {{ "sponsoredFamiliesInclude" | i18n }}: -
    -
  • {{ "sponsoredFamiliesPremiumAccess" | i18n }}
  • -
  • {{ "sponsoredFamiliesSharedCollections" | i18n }}
  • -
-
- -

{{ "sponsoredBitwardenFamilies" | i18n }}

- - @if (loading) { - - - {{ "loading" | i18n }} - - } - - @if (!loading && sponsoredFamilies?.length > 0) { - - - - - {{ "recipient" | i18n }} - {{ "status" | i18n }} - {{ "notes" | i18n }} - - - - - @for (o of sponsoredFamilies; let i = $index; track i) { - - - {{ o.sponsorshipEmail }} - {{ o.status }} - {{ o.sponsorshipNote }} - - - - - -
- - -
- - -
- } -
-
-
-
- } @else { -
- Search -

{{ "noSponsoredFamilies" | i18n }}

-

{{ "noSponsoredFamiliesDescription" | i18n }}

-
- } -
-
diff --git a/apps/web/src/app/billing/members/organization-sponsored-families.component.ts b/apps/web/src/app/billing/members/organization-sponsored-families.component.ts deleted file mode 100644 index 7cc46634a38..00000000000 --- a/apps/web/src/app/billing/members/organization-sponsored-families.component.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from "@angular/core"; -import { Subject } from "rxjs"; - -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; - -import { SponsoredFamily } from "./types/sponsored-family"; - -@Component({ - selector: "app-organization-sponsored-families", - templateUrl: "organization-sponsored-families.component.html", -}) -export class OrganizationSponsoredFamiliesComponent implements OnInit, OnDestroy { - loading = false; - tabIndex = 0; - - @Input() sponsoredFamilies: SponsoredFamily[] = []; - @Output() removeSponsorshipEvent = new EventEmitter(); - - private _destroy = new Subject(); - - constructor(private platformUtilsService: PlatformUtilsService) {} - - async ngOnInit() { - this.loading = false; - } - - get isSelfHosted(): boolean { - return this.platformUtilsService.isSelfHost(); - } - - remove(sponsorship: SponsoredFamily) { - this.removeSponsorshipEvent.emit(sponsorship); - } - - ngOnDestroy(): void { - this._destroy.next(); - this._destroy.complete(); - } -} diff --git a/apps/web/src/app/billing/settings/sponsored-families.component.html b/apps/web/src/app/billing/settings/sponsored-families.component.html index 12e942aaf18..8e829ae70ef 100644 --- a/apps/web/src/app/billing/settings/sponsored-families.component.html +++ b/apps/web/src/app/billing/settings/sponsored-families.component.html @@ -13,7 +13,7 @@ {{ "sponsoredFamiliesInclude" | i18n }}:
  • {{ "sponsoredFamiliesPremiumAccess" | i18n }}
  • -
  • {{ "sponsoredFamiliesSharedCollections" | i18n }}
  • +
  • {{ "sponsoredFamiliesSharedCollectionsMessage" | i18n }}
diff --git a/apps/web/src/app/billing/settings/sponsoring-org-row.component.html b/apps/web/src/app/billing/settings/sponsoring-org-row.component.html index eeeaa256049..1e5690cd85a 100644 --- a/apps/web/src/app/billing/settings/sponsoring-org-row.component.html +++ b/apps/web/src/app/billing/settings/sponsoring-org-row.component.html @@ -32,7 +32,7 @@ type="button" bitMenuItem (click)="revokeSponsorship()" - [attr.aria-label]="'revokeAccount' | i18n: sponsoringOrg.familySponsorshipFriendlyName" + [attr.aria-label]="'revokeAccountMessage' | i18n: sponsoringOrg.familySponsorshipFriendlyName" > {{ "remove" | i18n }} diff --git a/apps/web/src/app/shared/loose-components.module.ts b/apps/web/src/app/shared/loose-components.module.ts index bec06888c57..90e4c6ba9c3 100644 --- a/apps/web/src/app/shared/loose-components.module.ts +++ b/apps/web/src/app/shared/loose-components.module.ts @@ -62,8 +62,6 @@ import { PipesModule } from "../vault/individual-vault/pipes/pipes.module"; import { PurgeVaultComponent } from "../vault/settings/purge-vault.component"; import { FreeBitwardenFamiliesComponent } from "./../billing/members/free-bitwarden-families.component"; -import { OrganizationMemberFamiliesComponent } from "./../billing/members/organization-member-families.component"; -import { OrganizationSponsoredFamiliesComponent } from "./../billing/members/organization-sponsored-families.component"; import { EnvironmentSelectorModule } from "./../components/environment-selector/environment-selector.module"; import { AccountFingerprintComponent } from "./components/account-fingerprint/account-fingerprint.component"; import { SharedModule } from "./shared.module"; @@ -128,8 +126,6 @@ import { SharedModule } from "./shared.module"; SelectableAvatarComponent, SetPasswordComponent, SponsoredFamiliesComponent, - OrganizationSponsoredFamiliesComponent, - OrganizationMemberFamiliesComponent, FreeBitwardenFamiliesComponent, SponsoringOrgRowComponent, UpdatePasswordComponent, @@ -176,8 +172,6 @@ import { SharedModule } from "./shared.module"; SelectableAvatarComponent, SetPasswordComponent, SponsoredFamiliesComponent, - OrganizationSponsoredFamiliesComponent, - OrganizationMemberFamiliesComponent, FreeBitwardenFamiliesComponent, SponsoringOrgRowComponent, UpdateTempPasswordComponent, diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index 4650ded54bb..c81954ef9ca 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -6303,13 +6303,13 @@ "sponsoredBitwardenFamilies": { "message": "Sponsored families" }, - "noSponsoredFamilies": { + "noSponsoredFamiliesMessage": { "message": "No sponsored families" }, - "noSponsoredFamiliesDescription": { + "nosponsoredFamiliesDetails": { "message": "Sponsored non-member families plans will display here" }, - "sponsorFreeBitwardenFamilies": { + "sponsorshipFreeBitwardenFamilies": { "message": "Members of your organization are eligible for Free Bitwarden Families. You can sponsor Free Bitwarden Families for employees who are not a member of your Bitwarden organization. Sponsoring a non-member requires an available seat within your organization." }, "sponsoredFamiliesRemoveActiveSponsorship": { @@ -6327,8 +6327,8 @@ "sponsoredFamiliesPremiumAccess": { "message": "Premium access for up to 6 users" }, - "sponsoredFamiliesSharedCollections": { - "message": "Shared collections for Family secrets" + "sponsoredFamiliesSharedCollectionsMessage": { + "message": "Shared collections for family members" }, "memberFamilies": { "message": "Member families" @@ -6342,6 +6342,15 @@ "membersWithSponsoredFamilies": { "message": "Members of your organization are eligible for Free Bitwarden Families. Here you can see members who have sponsored a Families organization." }, + "organizationHasMemberMessage": { + "message": "A sponsorship cannot be sent to $EMAIL$ because they are a member of your organization.", + "placeholders": { + "email": { + "content": "$1", + "example": "mail@example.com" + } + } + }, "badToken": { "message": "The link is no longer valid. Please have the sponsor resend the offer." }, @@ -6393,7 +6402,7 @@ "redeemedAccount": { "message": "Account redeemed" }, - "revokeAccount": { + "revokeAccountMessage": { "message": "Revoke account $NAME$", "placeholders": { "name": { diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index 1cc2b591412..0d59f4a6547 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -136,11 +136,13 @@ import { import { AccountBillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions/account/account-billing-api.service.abstraction"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { OrganizationBillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions/organizations/organization-billing-api.service.abstraction"; +import { OrganizationSponsorshipApiServiceAbstraction } from "@bitwarden/common/billing/abstractions/organizations/organization-sponsorship-api.service.abstraction"; import { TaxServiceAbstraction } from "@bitwarden/common/billing/abstractions/tax.service.abstraction"; import { AccountBillingApiService } from "@bitwarden/common/billing/services/account/account-billing-api.service"; import { DefaultBillingAccountProfileStateService } from "@bitwarden/common/billing/services/account/billing-account-profile-state.service"; import { BillingApiService } from "@bitwarden/common/billing/services/billing-api.service"; import { OrganizationBillingApiService } from "@bitwarden/common/billing/services/organization/organization-billing-api.service"; +import { OrganizationSponsorshipApiService } from "@bitwarden/common/billing/services/organization/organization-sponsorship-api.service"; import { OrganizationBillingService } from "@bitwarden/common/billing/services/organization-billing.service"; import { TaxService } from "@bitwarden/common/billing/services/tax.service"; import { BulkEncryptService } from "@bitwarden/common/key-management/crypto/abstractions/bulk-encrypt.service"; @@ -1063,6 +1065,11 @@ const safeProviders: SafeProvider[] = [ // subscribes to sync notifications and will update itself based on that. deps: [ApiServiceAbstraction, SyncService], }), + safeProvider({ + provide: OrganizationSponsorshipApiServiceAbstraction, + useClass: OrganizationSponsorshipApiService, + deps: [ApiServiceAbstraction], + }), safeProvider({ provide: OrganizationBillingApiServiceAbstraction, useClass: OrganizationBillingApiService, diff --git a/libs/common/src/admin-console/models/request/organization/organization-sponsorship-create.request.ts b/libs/common/src/admin-console/models/request/organization/organization-sponsorship-create.request.ts index 19e993487c2..726bd6a85e1 100644 --- a/libs/common/src/admin-console/models/request/organization/organization-sponsorship-create.request.ts +++ b/libs/common/src/admin-console/models/request/organization/organization-sponsorship-create.request.ts @@ -6,5 +6,6 @@ export class OrganizationSponsorshipCreateRequest { sponsoredEmail: string; planSponsorshipType: PlanSponsorshipType; friendlyName: string; + isAdminInitiated?: boolean; notes?: string; } diff --git a/libs/common/src/billing/abstractions/organizations/organization-sponsorship-api.service.abstraction.ts b/libs/common/src/billing/abstractions/organizations/organization-sponsorship-api.service.abstraction.ts new file mode 100644 index 00000000000..e6e395c69df --- /dev/null +++ b/libs/common/src/billing/abstractions/organizations/organization-sponsorship-api.service.abstraction.ts @@ -0,0 +1,8 @@ +import { ListResponse } from "../../../models/response/list.response"; +import { OrganizationSponsorshipInvitesResponse } from "../../models/response/organization-sponsorship-invites.response"; + +export abstract class OrganizationSponsorshipApiServiceAbstraction { + abstract getOrganizationSponsorship( + sponsoredOrgId: string, + ): Promise>; +} diff --git a/libs/common/src/billing/models/response/organization-sponsorship-invites.response.ts b/libs/common/src/billing/models/response/organization-sponsorship-invites.response.ts new file mode 100644 index 00000000000..87a2cae4699 --- /dev/null +++ b/libs/common/src/billing/models/response/organization-sponsorship-invites.response.ts @@ -0,0 +1,31 @@ +import { BaseResponse } from "../../../models/response/base.response"; +import { PlanSponsorshipType } from "../../enums"; + +export class OrganizationSponsorshipInvitesResponse extends BaseResponse { + sponsoringOrganizationUserId: string; + friendlyName: string; + offeredToEmail: string; + planSponsorshipType: PlanSponsorshipType; + lastSyncDate?: Date; + validUntil?: Date; + toDelete = false; + isAdminInitiated: boolean; + notes: string; + statusMessage?: string; + statusClass?: string; + + constructor(response: any) { + super(response); + this.sponsoringOrganizationUserId = this.getResponseProperty("SponsoringOrganizationUserId"); + this.friendlyName = this.getResponseProperty("FriendlyName"); + this.offeredToEmail = this.getResponseProperty("OfferedToEmail"); + this.planSponsorshipType = this.getResponseProperty("PlanSponsorshipType"); + this.lastSyncDate = this.getResponseProperty("LastSyncDate"); + this.validUntil = this.getResponseProperty("ValidUntil"); + this.toDelete = this.getResponseProperty("ToDelete") ?? false; + this.isAdminInitiated = this.getResponseProperty("IsAdminInitiated"); + this.notes = this.getResponseProperty("Notes"); + this.statusMessage = this.getResponseProperty("StatusMessage"); + this.statusClass = this.getResponseProperty("StatusClass"); + } +} diff --git a/libs/common/src/billing/services/organization/organization-sponsorship-api.service.ts b/libs/common/src/billing/services/organization/organization-sponsorship-api.service.ts new file mode 100644 index 00000000000..bb420377439 --- /dev/null +++ b/libs/common/src/billing/services/organization/organization-sponsorship-api.service.ts @@ -0,0 +1,22 @@ +import { ApiService } from "../../../abstractions/api.service"; +import { ListResponse } from "../../../models/response/list.response"; +import { OrganizationSponsorshipApiServiceAbstraction } from "../../abstractions/organizations/organization-sponsorship-api.service.abstraction"; +import { OrganizationSponsorshipInvitesResponse } from "../../models/response/organization-sponsorship-invites.response"; + +export class OrganizationSponsorshipApiService + implements OrganizationSponsorshipApiServiceAbstraction +{ + constructor(private apiService: ApiService) {} + async getOrganizationSponsorship( + sponsoredOrgId: string, + ): Promise> { + const r = await this.apiService.send( + "GET", + "/organization/sponsorship/" + sponsoredOrgId + "/sponsored", + null, + true, + true, + ); + return new ListResponse(r, OrganizationSponsorshipInvitesResponse); + } +} From c9dcba2506b1d811cfcfd91b58f0d794b7b570a4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 1 May 2025 09:00:40 -0700 Subject: [PATCH 14/19] [deps]: Update docker/setup-qemu-action action to v3.6.0 (#14504) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build-web.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-web.yml b/.github/workflows/build-web.yml index 4ca6dc25aab..630e1e55682 100644 --- a/.github/workflows/build-web.yml +++ b/.github/workflows/build-web.yml @@ -196,7 +196,7 @@ jobs: } - name: Set up QEMU emulators - uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 + uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0 - name: Set up Docker Buildx uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 From a50b45c505bd839d965856429543b5310c2f647b Mon Sep 17 00:00:00 2001 From: cyprain-okeke <108260115+cyprain-okeke@users.noreply.github.com> Date: Thu, 1 May 2025 17:12:28 +0100 Subject: [PATCH 15/19] Resolve the typo (#14584) --- .../billing/members/free-bitwarden-families.component.html | 2 +- .../app/billing/settings/sponsored-families.component.html | 2 +- apps/web/src/locales/en/messages.json | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/web/src/app/billing/members/free-bitwarden-families.component.html b/apps/web/src/app/billing/members/free-bitwarden-families.component.html index a156eb608d5..9e32fb925a8 100644 --- a/apps/web/src/app/billing/members/free-bitwarden-families.component.html +++ b/apps/web/src/app/billing/members/free-bitwarden-families.component.html @@ -11,7 +11,7 @@ {{ "sponsorshipFreeBitwardenFamilies" | i18n }}

- {{ "sponsoredFamiliesInclude" | i18n }}: + {{ "sponsoredFamiliesIncludeMessage" | i18n }}: