Commit cac3d21c authored by NGPixel's avatar NGPixel

feat: self-contained auth modules + login UI + icons

parent 52630127
<svg xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" stroke-miterlimit="1.414" viewBox="0 0 159 158" clip-rule="evenodd" stroke-linejoin="round"><path fill="#51b5d7" d="M75.768.125c0 .07-.277.125-.617.125-.34 0-.65.057-.69.127-.04.07-.13.094-.2.053-.06-.04-.1 0-.08.092.03.113-.14.178-.51.205-.41.03-.56.097-.61.28-.04.182-.17.243-.49.243-.33 0-.45.06-.5.25-.05.19-.17.25-.5.25-.32 0-.45.06-.49.238-.03.13-.17.267-.3.3-.13.035-.24.147-.24.25 0 .112-.17.216-.43.266-.26.05-.43.156-.43.264 0 .1-.06.182-.14.182-.08 0-.23.103-.34.228-.11.124-.3.263-.42.308-.12.045-.22.167-.22.272 0 .106-.09.192-.2.192-.11 0-.23.113-.26.25s-.15.25-.25.25-.21.107-.24.238c-.03.13-.17.267-.3.3-.13.035-.24.146-.24.248 0 .102-.11.214-.25.25-.13.036-.25.15-.25.25 0 .102-.11.214-.25.25-.13.036-.25.15-.25.25s-.11.214-.25.25c-.13.036-.25.148-.25.25 0 .102-.11.214-.25.25-.13.036-.25.15-.25.25 0 .102-.11.214-.25.25-.13.036-.25.155-.25.264 0 .11-.09.2-.2.2-.11 0-.23.113-.26.25-.04.138-.15.25-.25.25s-.21.113-.25.25c-.04.137-.15.25-.25.25s-.21.107-.25.238c-.03.132-.17.267-.3.3-.13.036-.24.153-.24.263 0 .11-.09.2-.2.2-.11 0-.23.12-.26.25-.04.14-.15.25-.25.25s-.21.11-.25.24-.17.27-.3.3c-.13.04-.24.15-.24.25s-.11.21-.25.25c-.14.04-.25.15-.25.25s-.11.22-.25.25c-.14.04-.25.15-.25.25s-.11.22-.25.25c-.14.04-.25.15-.25.25s-.11.22-.25.25c-.14.04-.25.15-.25.25s-.11.22-.25.25c-.14.04-.25.16-.25.27 0 .11-.09.2-.2.2-.11 0-.22.11-.26.24-.03.13-.17.27-.3.3-.13.04-.24.15-.24.25s-.11.22-.25.25c-.14.04-.25.15-.25.25s-.11.22-.25.25c-.14.04-.25.15-.25.25s-.11.22-.25.25c-.14.04-.25.15-.25.25s-.11.22-.25.25c-.14.04-.25.15-.25.25s-.11.22-.25.25c-.14.04-.25.15-.25.25s-.11.22-.25.25c-.14.04-.25.15-.25.25s-.11.22-.25.25c-.14.04-.25.15-.25.25s-.11.22-.25.25c-.14.04-.25.15-.25.25s-.11.22-.25.25c-.14.04-.25.16-.25.27 0 .11-.09.2-.2.2-.11 0-.23.11-.26.25-.04.14-.15.25-.25.25-.11 0-.22.11-.25.25-.04.14-.15.25-.25.25-.11 0-.22.12-.25.25-.04.14-.15.25-.25.25s-.22.11-.25.25c-.04.14-.15.25-.25.25-.11 0-.22.11-.25.25-.04.14-.15.25-.25.25-.11 0-.22.11-.25.24-.04.13-.17.27-.3.3-.14.04-.24.15-.24.25s-.12.22-.25.25c-.14.04-.25.15-.25.25s-.12.22-.25.25c-.14.04-.25.15-.25.25s-.12.22-.25.25c-.14.04-.25.15-.25.25s-.12.22-.25.25c-.14.04-.25.15-.25.25s-.12.22-.25.25c-.14.04-.25.15-.25.25s-.12.22-.25.25c-.14.04-.25.15-.25.25s-.12.22-.25.25c-.14.04-.25.15-.25.25s-.12.22-.25.25c-.14.04-.25.15-.25.25s-.12.22-.25.25c-.14.04-.25.15-.25.25s-.12.22-.25.25c-.14.04-.25.15-.25.25s-.12.22-.25.25c-.14.04-.25.15-.25.25s-.12.22-.25.25c-.14.04-.25.15-.25.25s-.12.22-.25.25c-.14.04-.25.15-.25.25s-.12.22-.25.25c-.14.04-.25.16-.25.27 0 .11-.09.2-.2.2-.11 0-.23.11-.26.24-.04.13-.17.27-.3.3-.14.04-.24.15-.24.25 0 .11-.12.22-.25.25-.14.04-.25.15-.25.25 0 .11-.12.22-.25.25-.14.04-.25.15-.25.25 0 .11-.12.22-.25.25-.14.04-.25.15-.25.25 0 .11-.12.22-.25.25-.14.04-.25.15-.25.25 0 .11-.12.22-.25.25-.14.04-.25.15-.25.25 0 .11-.12.22-.25.25-.14.04-.25.15-.25.25 0 .11-.12.22-.25.25-.14.04-.25.15-.25.25 0 .11-.12.22-.25.25-.14.04-.25.15-.25.25 0 .11-.12.22-.25.25-.14.04-.25.15-.25.25 0 .11-.12.22-.25.25-.14.04-.25.15-.25.25 0 .11-.12.22-.25.25-.14.04-.25.15-.25.25 0 .11-.12.22-.25.25-.14.04-.25.15-.25.25 0 .11-.12.22-.25.25-.14.04-.25.15-.25.25 0 .11-.12.22-.25.25-.14.04-.25.15-.25.25 0 .11-.12.22-.25.25-.14.04-.25.15-.25.25 0 .11-.12.22-.25.25-.14.04-.25.15-.25.25 0 .11-.12.22-.25.25-.14.04-.25.15-.25.25 0 .11-.12.22-.25.25-.14.04-.25.15-.25.25 0 .11-.12.22-.25.25-.14.04-.25.15-.25.25 0 .11-.12.22-.25.25-.14.04-.25.15-.25.25 0 .11-.12.22-.25.25-.14.04-.25.15-.25.25 0 .11-.12.22-.25.25-.14.04-.25.16-.25.27 0 .11-.09.2-.2.2-.11 0-.23.12-.27.25-.04.14-.15.25-.25.25s-.21.12-.25.25c-.04.14-.15.25-.25.25s-.21.12-.25.25c-.04.14-.15.25-.25.25s-.21.12-.25.25c-.04.14-.15.25-.25.25s-.21.12-.25.25c-.04.14-.15.25-.25.25s-.21.11-.25.24-.17.27-.3.3c-.13.04-.24.15-.24.25 0 .11-.11.22-.25.25-.14.04-.25.15-.25.25 0 .11-.11.22-.25.25-.14.04-.25.15-.25.25 0 .11-.11.22-.25.25-.14.04-.25.15-.25.25 0 .11-.11.22-.25.25-.14.04-.25.15-.25.25 0 .11-.11.22-.25.25-.14.04-.25.15-.25.25 0 .11-.11.22-.25.25-.14.04-.25.15-.25.25s-.11.22-.25.25c-.14.04-.25.15-.25.25 0 .11-.11.22-.25.25-.14.04-.25.15-.25.25 0 .11-.11.22-.25.25-.14.04-.25.15-.25.25s-.11.22-.25.25c-.14.04-.25.15-.25.25 0 .11-.11.22-.25.25-.14.04-.25.15-.25.25 0 .11-.11.22-.25.25-.14.04-.25.15-.25.25s-.11.22-.25.25c-.14.04-.25.15-.25.25 0 .11-.11.22-.25.25-.14.04-.25.15-.25.25 0 .11-.11.22-.25.25-.14.04-.25.15-.25.25s-.11.22-.25.25c-.14.04-.25.15-.25.25 0 .11-.11.22-.25.25-.14.04-.25.15-.25.25 0 .11-.11.22-.25.25-.14.04-.25.15-.25.25s-.11.22-.25.25c-.14.04-.25.15-.25.25 0 .11-.11.22-.25.25-.14.04-.25.15-.25.25 0 .11-.11.22-.25.25-.14.04-.25.15-.25.25s-.11.22-.25.25c-.14.04-.25.15-.25.25 0 .11-.11.22-.25.25-.14.04-.25.15-.25.25 0 .11-.11.22-.25.25-.14.04-.25.15-.25.25s-.11.22-.25.25c-.14.04-.25.15-.25.25 0 .11-.11.22-.25.25-.14.04-.25.15-.25.25 0 .11-.11.22-.25.25-.14.04-.25.15-.25.25s-.11.22-.25.25c-.14.04-.25.15-.25.25 0 .11-.11.22-.25.25-.14.04-.25.15-.25.25 0 .11-.11.22-.25.25-.14.04-.25.15-.25.25s-.11.22-.25.25c-.14.04-.25.15-.25.25 0 .11-.11.22-.25.25-.14.04-.25.15-.25.25 0 .11-.11.22-.25.25-.14.04-.25.16-.25.27 0 .11-.09.2-.2.2-.11 0-.23.11-.26.24s-.17.27-.3.3c-.13.04-.24.15-.24.25s-.11.22-.25.25c-.14.04-.25.15-.25.25s-.11.21-.25.25c-.14.04-.25.15-.25.25s-.11.21-.25.25c-.14.04-.25.15-.25.25s-.11.22-.25.25c-.14.04-.25.15-.25.25s-.11.21-.25.25c-.14.04-.25.15-.25.25s-.11.21-.25.25c-.14.04-.25.15-.25.25s-.11.22-.25.25c-.14.04-.25.15-.25.25s-.11.21-.25.25c-.14.04-.25.15-.25.25s-.11.21-.25.25c-.14.04-.25.16-.25.27 0 .11-.09.2-.19.2-.11 0-.23.09-.27.19-.04.11-.29.42-.55.69-.26.27-.51.6-.55.73-.04.13-.16.27-.26.31-.1.04-.18.19-.18.32 0 .17-.08.26-.24.26-.17 0-.26.1-.28.35-.02.2-.11.33-.2.32-.08-.02-.15.01-.14.06.01.05-.01.18-.05.28-.04.1-.1.3-.12.44-.03.14-.12.24-.21.22-.08-.02-.12.02-.08.09.04.07.01.16-.06.2-.07.05-.12.17-.12.28 0 .11-.11.29-.24.41-.17.15-.25.41-.28.89-.03.48-.09.67-.2.65-.09-.02-.13.02-.09.09.04.07.02.15-.06.2-.07.05-.13.56-.13 1.14 0 .83-.04 1.06-.18 1.06-.31 0-.49 3.26-.19 3.44.07.04.09.13.05.19-.04.06 0 .1.09.08.13-.03.17.25.2 1.14.03.99.08 1.21.28 1.39.19.16.25.37.25.87 0 .55.04.66.25.72.19.05.25.17.25.5 0 .33.06.45.25.5.14.04.26.18.26.33.03.58.06.64.25.63.15-.01.23.12.28.47.05.31.14.48.26.48.11 0 .19.07.19.16s.11.24.25.34c.14.1.25.26.25.35 0 .09.09.2.2.24.26.1.74.58.84.84.04.11.16.2.25.2s.2.11.24.25c.04.14.15.25.25.25s.21.11.25.25c.04.14.16.25.27.25.11 0 .2.09.2.2 0 .11.11.23.25.26.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.22.25.25c.14.04.25.15.25.25s.11.21.24.25c.13.03.26.17.3.3.03.13.14.24.25.24.1 0 .22.11.25.25.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.15.25.25.25s.22.11.25.25c.04.14.16.25.27.25.11 0 .2.09.2.19s.14.24.31.31c.17.06.31.17.31.24s.13.16.28.21c.16.05.37.18.48.31.1.12.33.24.5.27.17.03.29.12.27.21-.02.09.02.13.09.09.07-.04.16-.01.2.06.04.07.17.12.27.12.11 0 .29.1.41.24.12.13.41.26.64.28.28.02.42.1.4.2-.02.09.02.13.09.09.07-.04.16-.02.2.05.04.07.33.12.63.12s.56.05.56.12c0 .08 1.48.12 4.19.12 2.71 0 4.19-.04 4.19-.12 0-.07.27-.13.6-.13.45 0 .64-.06.78-.25.12-.17.32-.25.6-.25.31 0 .44-.06.49-.25.03-.14.17-.26.33-.26.58-.03.64-.05.62-.26-.02-.15.07-.22.27-.22.16 0 .32-.06.37-.13.04-.07.13-.09.2-.05.06.04.1 0 .08-.09-.02-.09.1-.19.26-.21.16-.03.32-.15.36-.29.03-.13.14-.24.24-.24.1 0 .21-.11.25-.25.04-.13.15-.25.25-.25s.21-.11.25-.25c.03-.13.14-.25.24-.25.19 0 64.79-64.55 64.79-64.74 0-.16.55-.7.8-.8.11-.04.2-.15.2-.24s.12-.26.25-.38c.14-.11.25-.35.25-.51 0-.19.09-.32.25-.36.15-.04.25-.17.25-.32 0-.14.1-.37.22-.51s.25-.38.29-.54c.05-.15.15-.26.23-.24.09.02.12-.02.08-.09-.04-.06-.01-.15.06-.19.07-.05.13-.33.13-.64 0-.39.05-.55.17-.55.1 0 .21-.14.25-.32.13-.52.08-8.93-.06-8.93-.06 0-.11-.08-.11-.18s-.05-.18-.12-.18c-.07 0-.13-.26-.13-.57 0-.47-.04-.59-.25-.64-.19-.05-.25-.17-.25-.5 0-.33-.06-.45-.25-.5-.14-.04-.25-.18-.26-.33-.03-.58-.05-.64-.27-.63-.13.01-.22-.07-.22-.22 0-.13-.16-.41-.37-.63-.2-.212-.34-.44-.3-.5.04-.06-.01-.09-.09-.07-.09.02-.18-.1-.21-.26-.02-.16-.15-.32-.27-.36-.13-.03-.26-.16-.29-.3-.03-.13-.15-.24-.25-.24s-.21-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.13-.16-.25-.26-.25-.11 0-.2-.09-.2-.2 0-.11-.11-.22-.25-.26-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.1-.21-.24-.25c-.13-.03-.27-.17-.3-.3-.04-.13-.15-.24-.25-.24s-.22-.11-.25-.25c-.04-.14-.15-.25-.25-.25s-.22-.11-.25-.25c-.04-.14-.15-.25-.25-.25s-.22-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.22-.11-.25-.25c-.04-.14-.15-.25-.25-.25s-.22-.11-.25-.25c-.04-.14-.15-.25-.25-.25s-.22-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.22-.11-.25-.25c-.04-.14-.15-.25-.25-.25s-.22-.11-.25-.25c-.04-.14-.15-.25-.25-.25s-.22-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.22-.11-.25-.25c-.04-.14-.15-.25-.25-.25s-.22-.11-.25-.25c-.04-.14-.15-.25-.25-.25s-.22-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.22-.11-.25-.25c-.04-.14-.15-.25-.25-.25s-.22-.11-.25-.25c-.04-.14-.15-.25-.25-.25s-.22-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.22-.11-.25-.25c-.04-.14-.15-.25-.25-.25s-.22-.11-.25-.25c-.04-.14-.15-.25-.25-.25s-.22-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.22-.11-.25-.25c-.04-.14-.15-.25-.25-.25s-.22-.11-.25-.25c-.04-.14-.15-.25-.25-.25s-.22-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.22-.11-.25-.25c-.04-.14-.15-.25-.25-.25s-.22-.11-.25-.25c-.04-.14-.15-.25-.25-.25s-.22-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.22-.11-.25-.25c-.04-.14-.15-.25-.25-.25s-.22-.11-.25-.25c-.04-.14-.16-.25-.27-.25-.11 0-.2-.09-.2-.2 0-.11-.1-.22-.23-.26-.13-.03-.26-.17-.3-.3-.03-.13-.14-.24-.25-.24-.1 0-.21-.11-.25-.25-.04-.14-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.14-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.14-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.14-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.14-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.14-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.14-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.14-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.14-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.14-.16-.25-.26-.25-.11 0-.2-.09-.2-.2 0-.11-.11-.23-.25-.26-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.04-.25-.15-.25-.25s-.11-.21-.24-.25c-.13-.03-.27-.17-.3-.3-.03-.13-.15-.23-.25-.23s-.21-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.21-.11-.25-.25c-.03-.13-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.21-.11-.25-.25c-.03-.13-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.21-.11-.25-.25c-.03-.13-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.21-.11-.25-.25c-.03-.13-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.21-.11-.25-.25c-.03-.13-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.21-.11-.25-.25c-.03-.13-.15-.25-.25-.25s-.21-.11-.25-.25c-.04-.13-.15-.25-.26-.25-.11 0-.2-.09-.2-.2 0-.11-.11-.22-.25-.26-.14-.03-.25-.14-.25-.25 0-.1-.11-.21-.25-.25-.14-.03-.25-.14-.25-.25 0-.1-.11-.21-.25-.25-.14-.03-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.03-.25-.14-.25-.25 0-.1-.11-.21-.25-.25-.14-.03-.25-.14-.25-.25 0-.1-.11-.21-.25-.25-.14-.03-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.03-.25-.14-.25-.25 0-.1-.11-.21-.25-.25-.14-.03-.25-.14-.25-.25 0-.1-.11-.21-.25-.25-.14-.03-.25-.15-.25-.25s-.11-.21-.25-.25c-.14-.03-.25-.14-.25-.25 0-.1-.11-.21-.25-.25-.14-.03-.25-.14-.25-.25 0-.1-.11-.21-.25-.25-.14-.03-.25-.15-.25-.25s-.11-.21-.24-.24-.27-.17-.3-.3c-.04-.13-.15-.24-.25-.24s-.22-.11-.25-.25c-.04-.14-.15-.25-.25-.25s-.22-.11-.25-.25c-.04-.14-.15-.25-.25-.25s-.22-.11-.25-.25c-.04-.13-.15-.25-.25-.25s-.22-.11-.25-.25c-.04-.14-.16-.25-.27-.25-.11 0-.2-.08-.2-.19 0-.1-.1-.23-.22-.27-.12-.05-.31-.19-.42-.31-.11-.13-.27-.23-.35-.23-.08 0-.14-.08-.14-.18 0-.11-.17-.22-.43-.26-.27-.05-.45-.17-.49-.32-.033-.13-.17-.24-.304-.24-.13 0-.37-.12-.53-.25-.16-.14-.39-.25-.52-.25s-.23-.08-.23-.18c0-.19-.37-.32-.94-.33-.23 0-.45-.09-.56-.25-.13-.19-.32-.25-.77-.25-.33 0-.6-.05-.6-.12.02-.07-1.27-.12-3.6-.12S75.8.1 75.8.18m6.09 23.5c.39.14.852.25 1.03.25.17 0 .482.12.69.25.204.14.5.25.66.25.15 0 .375.11.492.25.12.14.334.25.48.25.146 0 .37.12.49.25.126.14.3.25.39.25.09 0 .23.07.32.16s.39.32.65.52c.62.47 1.69 1.54 2.16 2.16.197.27.43.53.516.59.08.058.15.2.15.327s.11.326.25.45c.13.125.25.346.25.49 0 .14.11.36.25.48.13.11.25.34.25.49 0 .16.11.45.25.66.13.207.25.544.25.75 0 .207.09.544.21.75.36.63.39 4.41.04 5.29-.14.37-.26.84-.26 1.05 0 .22-.09.49-.2.62-.11.12-.23.44-.27.72l-.07.5 13.03 13c7.16 7.16 13.09 13.02 13.17 13.02.087 0 .368-.11.62-.25.26-.13.66-.25.9-.25s.526-.09.65-.22c.36-.36 5.26-.39 5.85-.03.22.14.61.26.85.26.25 0 .57.11.75.25.175.134.456.25.62.25.17 0 .41.11.53.25.13.134.32.25.44.25s.314.11.44.25.28.25.34.25c.31 0 2.845 2.23 2.845 2.51 0 .04.14.24.31.44.49.56.53.62.74 1.063.11.23.36.7.56 1.04.2.35.37.75.38.91 0 .153.12.49.26.75.14.274.25.704.25 1.05 0 .32.09.83.2 1.13.24.67.28 2.55.06 2.96-.08.16-.184.66-.224 1.13-.04.48-.17 1.01-.31 1.23-.13.21-.23.53-.23.7 0 .17-.11.452-.25.63s-.25.43-.25.56c0 .13-.11.34-.25.47-.14.12-.25.3-.25.4 0 .192-1.24 1.79-1.4 1.79-.06 0-.11.06-.11.13 0 .13-.67.86-.79.86-.03 0-.29.21-.57.47-.72.66-1.21 1.03-1.39 1.03-.08 0-.29.11-.46.25-.17.14-.4.25-.5.25-.1 0-.32.11-.5.25s-.51.25-.75.25-.57.11-.75.25c-.25.2-.51.25-1.28.25-.65 0-1.04.06-1.2.18-.31.23-1.69.25-1.92.03-.09-.09-.64-.19-1.3-.23-.72-.04-1.16-.125-1.19-.22-.13-.4-1.28.7-13.17 12.58-13.59 13.58-13 12.93-12.49 13.7.13.2.25.53.25.71 0 .19.09.58.21.878.18.445.22.934.22 2.91 0 1.98-.04 2.47-.22 2.91-.12.296-.22.675-.22.846 0 .17-.11.52-.25.78s-.25.62-.25.8c0 .18-.12.46-.25.62-.14.16-.25.38-.25.5 0 .115-.12.31-.25.44-.14.12-.25.33-.25.454 0 .13-.12.33-.25.45-.14.12-.25.26-.25.32 0 .32-1.97 2.52-2.86 3.19-.25.185-.54.42-.66.524-.46.4-.6.49-1.02.66-.24.1-.47.243-.52.32-.05.08-.19.14-.31.14s-.37.11-.54.25c-.18.14-.43.25-.55.25-.13 0-.4.11-.61.25-.21.14-.58.25-.84.25-.27 0-.55.09-.68.22-.32.32-6.64.33-7.01.01-.13-.114-.49-.234-.82-.27-.32-.04-.67-.16-.79-.27-.11-.11-.34-.203-.52-.203-.17 0-.45-.11-.63-.25-.17-.14-.38-.25-.47-.25-.08 0-.28-.11-.44-.25-.16-.14-.39-.25-.52-.25-.12 0-.3-.11-.38-.25-.08-.14-.21-.25-.27-.25-.06 0-.2-.08-.31-.19-.11-.11-.52-.45-.92-.76s-1.04-.98-1.42-1.47c-.39-.49-.77-.96-.86-1.03-.08-.07-.33-.46-.55-.87-.22-.41-.48-.84-.58-.95-.1-.11-.18-.3-.18-.42s-.11-.37-.25-.54c-.14-.18-.25-.49-.25-.7 0-.21-.11-.55-.23-.77-.13-.21-.27-.74-.32-1.18-.04-.43-.15-.91-.23-1.06-.24-.44-.19-3.63.07-4.33.12-.3.21-.77.21-1.06 0-.3.1-.67.25-.89.15-.22.25-.58.25-.89v-.52L53 103.39c-6.95-6.952-12.73-12.64-12.842-12.636-.11.002-.31.087-.444.187-.16.13-.544.19-1.125.19-.54 0-1.03.08-1.25.19-.43.23-1.37.25-1.75.04-.15-.08-.79-.18-1.43-.22-.82-.05-1.22-.14-1.39-.29-.13-.11-.43-.21-.68-.21-.26 0-.58-.1-.76-.25-.18-.13-.4-.25-.5-.25-.1 0-.25-.08-.34-.18-.09-.1-.27-.22-.41-.26-1.07-.34-4.19-3.46-4.53-4.53-.04-.14-.16-.32-.26-.4-.1-.08-.18-.25-.18-.37s-.11-.36-.25-.53c-.14-.17-.25-.5-.25-.71 0-.22-.11-.54-.25-.71-.19-.24-.25-.51-.25-1.08 0-.42-.07-.99-.14-1.26-.25-.89-.27-1.62-.06-2.24.11-.32.2-.92.2-1.33 0-.5.08-.89.25-1.21.14-.25.25-.59.25-.73 0-.32.61-1.56.84-1.71.08-.05.16-.21.16-.35 0-.3 1.83-2.6 2.4-3 .37-.27.56-.43 1.1-.92.11-.1.24-.18.29-.18.05 0 .24-.11.41-.25s.41-.25.53-.25c.12 0 .32-.11.44-.25.13-.14.34-.25.48-.25.14 0 .35-.08.46-.19.12-.11.49-.24.83-.29.34-.05.75-.19.91-.31.49-.34 5.31-.31 5.96.04.26.14.6.25.75.25.16 0 .49.12.75.25.98.53.01 1.41 13.94-12.53 13-13 13.21-13.22 12.9-13.48-.1-.08-.18-.31-.18-.51s-.12-.51-.25-.69c-.17-.2-.25-.5-.25-.86 0-.3-.1-.78-.22-1.08-.3-.72-.3-3 0-3.96.12-.37.22-.88.22-1.14 0-.27.1-.59.25-.78.14-.17.25-.47.26-.67 0-.19.17-.63.37-.98.2-.34.45-.82.56-1.06.11-.24.28-.48.37-.54.1-.05.18-.15.18-.21 0-.23 1.59-1.92 2.36-2.5.22-.17.5-.41.62-.53.11-.12.27-.22.35-.22.08 0 .28-.11.46-.25.17-.14.4-.25.49-.25.1 0 .28-.11.41-.25s.34-.25.49-.25c.14 0 .47-.11.73-.25s.59-.25.75-.25c.15 0 .59-.11.97-.25 1-.36 4.06-.36 5.08 0M60.62 64.4L48.83 76.2v2.63c0 2.38-.024 2.674-.25 3.12-.14.27-.25.65-.25.85 0 .2-.11.51-.25.68-.14.18-.25.45-.25.606 0 .16-.12.41-.26.57-.71.754-1.4-.025 11.58 12.96 12.717 12.71 12.117 12.16 12.83 11.61.16-.127.396-.267.517-.31.26-.094.29-56.22.03-56.286-.06-.02-5.42 5.28-11.9 11.77M85.97 52.6c-.19.197-.07 56.28.12 56.28.11 0 .35.11.53.248.87.62-.15 1.53 12.94-11.56 6.58-6.58 11.967-12.02 11.967-12.11 0-.08-.055-.2-.12-.26-.22-.22-.757-1.312-.757-1.54 0-.125-.11-.37-.25-.545-.14-.18-.25-.505-.25-.75 0-.24-.114-.693-.255-1.013-.23-.524-.254-.8-.23-2.87l.03-2.294-11.82-11.82c-6.5-6.5-11.855-11.79-11.895-11.75"/><path fill="#97cbe1" d="M76.773 23.63c-.375.134-.81.245-.97.245-.156 0-.495.112-.752.25-.25.138-.58.25-.73.25-.14 0-.36.112-.49.25-.12.138-.3.25-.4.25-.1 0-.32.113-.5.25-.17.137-.38.25-.46.25-.08 0-.23.1-.35.22-.11.12-.39.358-.62.53-.76.58-2.35 2.27-2.35 2.505 0 .06-.08.153-.17.208-.09.054-.26.296-.37.537-.11.24-.36.72-.56 1.062-.2.345-.37.786-.37.98 0 .196-.12.5-.25.674-.15.19-.25.51-.25.78 0 .26-.1.77-.21 1.14-.3.96-.3 3.24 0 3.96.12.3.22.78.22 1.08 0 .36.09.66.25.86.14.18.25.49.25.69 0 .21.08.44.18.52.32.26.1.49-12.89 13.48-13.97 13.93-13 13.06-13.98 12.53-.25-.14-.59-.25-.75-.25-.15 0-.49-.11-.75-.25-.65-.35-5.47-.38-5.96-.04-.16.12-.58.26-.92.31-.34.06-.71.19-.83.29-.12.11-.32.2-.46.2s-.35.11-.48.25c-.12.14-.32.25-.44.25-.11 0-.35.12-.53.25-.17.14-.36.25-.41.25-.05 0-.18.08-.29.18-.54.5-.73.66-1.1.93-.57.41-2.4 2.7-2.4 3.01 0 .14-.07.3-.16.35-.23.15-.84 1.39-.84 1.71 0 .15-.11.48-.25.74-.17.32-.25.71-.25 1.21 0 .41-.09 1.01-.2 1.33-.2.61-.18 1.35.06 2.24.08.28.14.85.14 1.27.01.57.07.84.26 1.08.14.18.25.5.25.72 0 .22.12.54.25.72.14.18.25.42.25.54 0 .12.09.29.19.37.1.08.22.26.27.4.34 1.07 3.47 4.2 4.53 4.54.14.04.32.16.4.26.09.1.24.18.34.18.1 0 .33.12.5.25.18.15.51.25.76.25s.55.1.68.21c.16.15.56.24 1.38.29.63.05 1.27.15 1.42.23.38.21 1.32.19 1.75-.04.22-.11.7-.18 1.24-.18.58 0 .97-.06 1.13-.18.13-.1.33-.18.44-.18.11 0 5.89 5.69 12.85 12.64l12.64 12.64v.52c0 .31-.1.67-.24.89-.15.22-.25.59-.25.89 0 .29-.1.76-.21 1.07-.27.7-.32 3.89-.07 4.33.08.15.19.63.23 1.06.04.43.18.96.31 1.18.13.22.23.56.23.77 0 .21.11.52.25.7.14.18.25.42.25.54 0 .12.08.31.18.42.1.11.36.54.58.95.22.41.47.8.55.87.09.07.47.53.86 1.03.39.49 1.03 1.15 1.43 1.47.4.31.81.65.92.76.11.1.25.18.32.18.06 0 .18.12.27.25.09.14.26.25.39.25s.36.12.52.25c.16.14.36.25.44.25.08 0 .3.12.47.25.17.14.46.25.63.25s.41.1.52.21c.11.11.47.23.79.27.33.04.69.16.82.27.37.31 6.69.3 7.01-.02.13-.13.41-.22.68-.22.25 0 .63-.12.84-.25.21-.14.48-.25.61-.25s.37-.12.55-.25c.17-.14.42-.25.54-.25.12 0 .26-.07.31-.14.04-.08.28-.22.52-.32.42-.18.56-.27 1.01-.67.12-.1.42-.34.66-.52.89-.67 2.86-2.87 2.86-3.19 0-.06.11-.2.25-.32s.25-.32.25-.45.11-.33.25-.45.25-.32.25-.44.11-.34.25-.5c.14-.16.25-.43.25-.61s.11-.54.25-.79c.14-.26.25-.61.25-.78 0-.17.1-.55.22-.84.19-.45.22-.94.22-2.91 0-1.98-.03-2.47-.22-2.91-.12-.3-.22-.69-.22-.88 0-.19-.11-.51-.24-.72-.51-.77-1.1-.12 12.49-13.7 11.88-11.9 13.03-13 13.16-12.6.04.09.48.17 1.2.218.65.04 1.2.14 1.29.23.22.22 1.61.2 1.91-.03.16-.13.55-.19 1.2-.19.77 0 1.02-.05 1.28-.25.18-.14.51-.25.75-.25s.57-.11.75-.25c.18-.137.4-.25.5-.25.1 0 .33-.11.5-.25.18-.138.39-.25.47-.25.17 0 .67-.367 1.39-1.03.28-.26.54-.47.57-.47.12 0 .79-.73.79-.866 0-.07.047-.13.1-.13.16 0 1.4-1.59 1.4-1.79 0-.09.11-.27.25-.4.14-.12.25-.33.25-.462 0-.14.11-.39.25-.56.14-.18.25-.46.25-.63 0-.173.106-.49.23-.703.14-.22.27-.75.31-1.23.04-.46.14-.97.22-1.12.22-.41.177-2.29-.063-2.96-.11-.3-.2-.81-.2-1.13 0-.34-.1-.77-.25-1.05-.14-.25-.26-.59-.26-.75 0-.15-.17-.56-.38-.9-.2-.35-.45-.82-.56-1.05-.21-.45-.25-.5-.74-1.07-.17-.2-.31-.4-.31-.44 0-.27-2.53-2.5-2.85-2.5-.06 0-.22-.11-.34-.25-.12-.14-.32-.25-.44-.25-.11 0-.31-.11-.43-.25s-.36-.25-.53-.25c-.16 0-.44-.11-.62-.25s-.5-.25-.75-.25c-.24 0-.63-.12-.85-.26-.58-.36-5.48-.33-5.85.04-.12.12-.4.22-.64.22s-.64.11-.9.25c-.26.13-.54.25-.62.25-.09 0-6.02-5.86-13.18-13.02l-13.1-13.1.07-.49c.04-.27.16-.6.27-.72.11-.12.2-.4.2-.61 0-.22.12-.69.26-1.06.35-.88.32-4.66-.04-5.29-.12-.21-.216-.55-.217-.75-.005-.21-.117-.55-.25-.75-.14-.21-.25-.5-.25-.66 0-.16-.116-.38-.25-.5-.14-.12-.25-.34-.25-.48 0-.15-.116-.37-.25-.49-.14-.13-.25-.33-.25-.45 0-.13-.07-.27-.16-.33-.087-.06-.32-.32-.518-.59-.47-.62-1.54-1.69-2.16-2.16-.27-.2-.56-.43-.65-.52-.09-.08-.24-.15-.326-.15-.09 0-.26-.12-.39-.25-.123-.14-.344-.25-.49-.25-.146 0-.36-.11-.48-.25-.116-.14-.34-.25-.495-.25-.154 0-.45-.12-.66-.25-.202-.14-.513-.25-.69-.25-.172 0-.635-.12-1.03-.25-1.02-.36-4.08-.36-5.084 0m4.42.3c.75.11 1.533.28 1.75.37.21.09.53.21.7.25.28.07.65.25 2 .94 1.1.56 3.56 3.03 4.13 4.13.1.2.34.66.52 1.02.82 1.6 1.45 4.75 1.23 6.16-.26 1.65-.5 2.83-.61 2.98-.07.08-.16.3-.2.5-.13.54-.79 1.88-1.17 2.37-.19.24-.46.59-.6.78-.55.75-1.13 1.33-2.04 2.02-.53.4-1.09.86-1.24 1.03l-.28.31v30.97l-.01 30.96.47.35c.25.19.73.49 1.06.65l.59.3.32-.3c1.72-1.6 24.05-24.07 24.05-24.2 0-.1-.22-.61-.49-1.14-.76-1.52-.91-1.91-1.1-2.91-.35-1.86-.4-2.64-.23-3.75.09-.58.17-1.25.17-1.48 0-.42.42-1.83.71-2.4.09-.17.32-.62.51-1 1.15-2.28 3.91-4.64 6.36-5.44 2.09-.69 5.09-1.04 5.96-.71.16.06.65.18 1.1.26.75.13 1.93.51 2.37.76.1.06.52.28.94.5.98.51 2.32 1.62 3.1 2.55.34.41.66.78.7.81.11.09.54.76.72 1.12.08.17.21.4.27.5.3.47.61 1.23.69 1.68.05.27.16.64.25.81.79 1.55.22 6.77-.94 8.63-.07.1-.17.31-.24.47-.57 1.32-3.74 4.53-4.48 4.53-.06 0-.25.1-.41.22-.31.23-.98.5-2.55 1.03-1.26.43-4.83.44-6.03.02-.56-.2-.85-.24-1.06-.16-.7.28-25.64 25.47-25.63 25.89.01.22.15.86.32 1.42.71 2.37.73 6.19.02 7.84-.11.24-.24.66-.3.93-.07.28-.26.75-.43 1.06-.18.31-.47.85-.65 1.21-.5.98-1.99 2.77-2.99 3.59-.49.41-.92.78-.96.83-.07.1-.77.51-1.94 1.13-4.75 2.54-11.66 1.74-15.5-1.8-.34-.32-.66-.58-.71-.58-.13 0-2.08-2.44-2.23-2.77-.07-.16-.19-.4-.28-.54-.43-.71-.55-.93-.81-1.56-.16-.38-.29-.77-.29-.88 0-.1-.11-.42-.24-.71-.59-1.3-.6-6.05-.02-7.7.53-1.52.54-1.56.32-1.9-.11-.18-5.89-6-12.84-12.95L40.41 90.3l-.49.08c-.28.04-.7.17-.95.274-.77.33-4.59.28-5.61-.078-.43-.154-.86-.277-.96-.277-.19 0-1.12-.43-2.15-.98-1.47-.79-3.85-3.17-4.45-4.46-.13-.28-.29-.59-.35-.69-.31-.53-.6-1.24-.69-1.69-.05-.28-.18-.67-.29-.88-.3-.56-.3-5.2 0-5.76.11-.21.24-.6.29-.87.08-.45.39-1.2.69-1.69.06-.11.18-.33.27-.5.5-1.03 1.55-2.26 2.94-3.48.75-.66.926-.77 2.21-1.43 3.337-1.72 7.474-1.71 11.19.02 1.59.74 4.044 3.02 4.724 4.39.086.17.3.56.477.87 1.82 3.19 1.59 9.35-.44 11.8-.27.33.26.89 12.09 12.75L71 109.84l.568-.17c.314-.09.67-.26.79-.36.12-.1.26-.19.32-.19s.21-.09.33-.2c.24-.22.36-48.07.144-58.35l-.083-3.98-.93-.76c-.51-.42-1.02-.81-1.14-.87-.24-.12-2.27-2.64-2.27-2.81 0-.07-.09-.19-.19-.27-.11-.09-.19-.24-.19-.35 0-.11-.11-.42-.24-.7-.97-2.08-1.3-6.66-.58-8.07.09-.18.21-.55.26-.82.08-.45.51-1.38.79-1.73.06-.08.15-.28.2-.45.05-.18.44-.74.86-1.25.75-.93 1.41-1.57 2.66-2.62.08-.07.53-.33 1-.57.47-.25.94-.5 1.04-.56.4-.24 1.48-.54 2.56-.71.62-.1 1.32-.23 1.56-.29.49-.12.73-.11 2.67.17m-2.93 5.34c-.18.07-.58.18-.9.24-.65.125-2.12.95-2.68 1.508-2.72 2.67-2.79 7.11-.15 9.75 2.39 2.38 6.81 2.52 9.19.28.08-.08.2-.17.26-.19.22-.09 1.03-1.27 1.38-2.02 1.64-3.48.17-7.435-3.36-9.05-1.21-.55-3.04-.81-3.75-.52m-5.5 51.41c.03 26.666.02 28.09-.19 28.17-.12.04-.35.18-.52.306-.72.55-.11 1.1-12.83-11.615-12.98-12.98-12.28-12.2-11.57-12.96.14-.16.26-.41.26-.57 0-.16.11-.43.25-.61.13-.18.25-.49.25-.69 0-.2.11-.59.25-.86.22-.45.25-.74.25-3.12V76.1l11.78-11.8c6.48-6.49 11.84-11.79 11.9-11.77.09.02.14 9.525.16 28.12m36.92-2.217c-.03 2.07 0 2.35.23 2.87.14.32.25.776.25 1.014 0 .24.11.57.25.75.13.17.25.42.25.54 0 .23.53 1.33.75 1.55.06.064.12.184.12.265 0 .08-5.39 5.53-11.96 12.104-13.1 13.097-12.08 12.187-12.95 11.567-.19-.135-.43-.245-.53-.245-.2 0-.32-56.084-.12-56.28.04-.04 5.39 5.247 11.89 11.75l11.82 11.824-.02 2.29m-74.2-6.34c-.27.05-.61.15-.75.225-.13.07-.45.17-.7.214-.25.05-.53.17-.61.27-.08.1-.23.18-.32.18s-.49.26-.89.58c-3.63 2.9-3.1 9.05.96 11.1l1.06.55c.67.35 3.4.36 4.35.02 2.14-.78 3.38-2.07 4.41-4.59 1.65-4.05-3.03-9.37-7.51-8.54m85.88-.05l-1.06.33c-.52.16-1.02.35-1.13.44-.1.08-.3.19-.44.23-.28.08-1.28 1-1.87 1.72-1.13 1.36-1.73 3.94-1.27 5.38.1.3.21.71.26.91.23 1 1.97 3.1 2.96 3.58 1.69.83 1.55.8 3.48.8 1.44 0 1.89-.04 2.19-.2.2-.11.51-.27.69-.35 1.94-.9 3.39-2.89 3.65-5.04.15-1.25-.01-2.99-.32-3.49-.1-.16-.23-.42-.28-.6-.18-.62-2-2.62-2.37-2.62-.08 0-.28-.1-.44-.23-.67-.51-3.32-1.06-4.05-.83M77.54 113.5c-.75.1-2.135.59-2.55.902-.164.126-.34.23-.394.23-.38 0-2.22 1.95-2.76 2.91-2.56 4.6-.62 9.93 4.39 12.06 1.31.553 4.2.64 5.33.15.29-.12.69-.26.9-.302.21-.04.448-.16.53-.26.09-.1.23-.18.31-.18.19 0 1.35-.87 1.81-1.36 3.52-3.68 3.17-9.38-.75-12.52-.43-.34-.84-.62-.92-.62-.08 0-.21-.06-.28-.14-.72-.72-3.468-1.15-5.597-.86"/></svg>
\ No newline at end of file
<svg width="100%" height="100%" viewBox="0 0 500 500" preserveAspectRatio="xMinYMin meet">
<path fill="#3B5998" d="M288.714,500l0,-228.073l76.554,0l11.461,-88.885l-88.017,0l0,-56.749c0,-25.735 7.145,-43.271 44.049,-43.271l47.067,-0.022l0,-79.498c-8.141,-1.081 -36.082,-3.502 -68.584,-3.502c-67.862,0 -114.321,41.422 -114.321,117.492l0,65.55l-76.751,0l0,88.885l76.751,0l0,228.071l91.791,0l0,0.002Z" style="fill-rule:nonzero;"/>
</svg>
\ No newline at end of file
<svg width="2500" height="2432" viewBox="0 0 256 249" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet"><g fill="#161614"><path d="M127.505 0C57.095 0 0 57.085 0 127.505c0 56.336 36.534 104.13 87.196 120.99 6.372 1.18 8.712-2.766 8.712-6.134 0-3.04-.119-13.085-.173-23.739-35.473 7.713-42.958-15.044-42.958-15.044-5.8-14.738-14.157-18.656-14.157-18.656-11.568-7.914.872-7.752.872-7.752 12.804.9 19.546 13.14 19.546 13.14 11.372 19.493 29.828 13.857 37.104 10.6 1.144-8.242 4.449-13.866 8.095-17.05-28.32-3.225-58.092-14.158-58.092-63.014 0-13.92 4.981-25.295 13.138-34.224-1.324-3.212-5.688-16.18 1.235-33.743 0 0 10.707-3.427 35.073 13.07 10.17-2.826 21.078-4.242 31.914-4.29 10.836.048 21.752 1.464 31.942 4.29 24.337-16.497 35.029-13.07 35.029-13.07 6.94 17.563 2.574 30.531 1.25 33.743 8.175 8.929 13.122 20.303 13.122 34.224 0 48.972-29.828 59.756-58.22 62.912 4.573 3.957 8.648 11.717 8.648 23.612 0 17.06-.148 30.791-.148 34.991 0 3.393 2.295 7.369 8.759 6.117 50.634-16.879 87.122-64.656 87.122-120.973C255.009 57.085 197.922 0 127.505 0"/><path d="M47.755 181.634c-.28.633-1.278.823-2.185.389-.925-.416-1.445-1.28-1.145-1.916.275-.652 1.273-.834 2.196-.396.927.415 1.455 1.287 1.134 1.923M54.027 187.23c-.608.564-1.797.302-2.604-.589-.834-.889-.99-2.077-.373-2.65.627-.563 1.78-.3 2.616.59.834.899.996 2.08.36 2.65M58.33 194.39c-.782.543-2.06.034-2.849-1.1-.781-1.133-.781-2.493.017-3.038.792-.545 2.05-.055 2.85 1.07.78 1.153.78 2.513-.019 3.069M65.606 202.683c-.699.77-2.187.564-3.277-.488-1.114-1.028-1.425-2.487-.724-3.258.707-.772 2.204-.555 3.302.488 1.107 1.026 1.445 2.496.7 3.258M75.01 205.483c-.307.998-1.741 1.452-3.185 1.028-1.442-.437-2.386-1.607-2.095-2.616.3-1.005 1.74-1.478 3.195-1.024 1.44.435 2.386 1.596 2.086 2.612M85.714 206.67c.036 1.052-1.189 1.924-2.705 1.943-1.525.033-2.758-.818-2.774-1.852 0-1.062 1.197-1.926 2.721-1.951 1.516-.03 2.758.815 2.758 1.86M96.228 206.267c.182 1.026-.872 2.08-2.377 2.36-1.48.27-2.85-.363-3.039-1.38-.184-1.052.89-2.105 2.367-2.378 1.508-.262 2.857.355 3.049 1.398"/></g></svg>
\ No newline at end of file
<svg width="2443" height="2500" viewBox="0 0 256 262" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid"><path d="M255.878 133.451c0-10.734-.871-18.567-2.756-26.69H130.55v48.448h71.947c-1.45 12.04-9.283 30.172-26.69 42.356l-.244 1.622 38.755 30.023 2.685.268c24.659-22.774 38.875-56.282 38.875-96.027" fill="#4285F4"/><path d="M130.55 261.1c35.248 0 64.839-11.605 86.453-31.622l-41.196-31.913c-11.024 7.688-25.82 13.055-45.257 13.055-34.523 0-63.824-22.773-74.269-54.25l-1.531.13-40.298 31.187-.527 1.465C35.393 231.798 79.49 261.1 130.55 261.1" fill="#34A853"/><path d="M56.281 156.37c-2.756-8.123-4.351-16.827-4.351-25.82 0-8.994 1.595-17.697 4.206-25.82l-.073-1.73L15.26 71.312l-1.335.635C5.077 89.644 0 109.517 0 130.55s5.077 40.905 13.925 58.602l42.356-32.782" fill="#FBBC05"/><path d="M130.55 50.479c24.514 0 41.05 10.589 50.479 19.438l36.844-35.974C195.245 12.91 165.798 0 130.55 0 79.49 0 35.393 29.301 13.925 71.947l42.211 32.783c10.59-31.477 39.891-54.251 74.414-54.251" fill="#EB4335"/></svg>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="48px" height="48px" viewBox="0 0 48 48" enable-background="new 0 0 48 48" xml:space="preserve">
<path fill="#458BC4" d="M44.804,30.404l-20-27C24.615,3.15,24.308,3.023,24,3.023V46c0.2,0,0.401-0.061,0.573-0.181l20-14
c0.222-0.155,0.37-0.393,0.414-0.659C45.03,30.895,44.964,30.622,44.804,30.404z"/>
<path fill="#43A6DD" d="M23.196,3.405l-20,27c-0.16,0.218-0.227,0.49-0.184,0.756c0.044,0.267,0.192,0.504,0.414,0.659l20,14
C23.599,45.939,23.8,46,24,46V3.023C23.692,3.023,23.385,3.15,23.196,3.405z"/>
</svg>
<svg width="2490" height="2500" viewBox="0 0 256 257" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid"><path d="M0 36.357L104.62 22.11l.045 100.914-104.57.595L0 36.358zm104.57 98.293l.08 101.002L.081 221.275l-.006-87.302 104.494.677zm12.682-114.405L255.968 0v121.74l-138.716 1.1V20.246zM256 135.6l-.033 121.191-138.716-19.578-.194-101.84L256 135.6z" fill="#00ADEF"/></svg>
\ No newline at end of file
<svg width="2500" height="2500" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid"><path d="M165.964 15.838c-3.89-11.975-16.752-18.528-28.725-14.636-11.975 3.89-18.528 16.752-14.636 28.725l58.947 181.365c4.048 11.187 16.132 17.473 27.732 14.135 12.1-3.483 19.475-16.334 15.614-28.217L165.964 15.838" fill="#DFA22F"/><path d="M74.626 45.516C70.734 33.542 57.873 26.989 45.9 30.879 33.924 34.77 27.37 47.631 31.263 59.606l58.948 181.366c4.047 11.186 16.132 17.473 27.732 14.132 12.099-3.481 19.474-16.332 15.613-28.217L74.626 45.516" fill="#3CB187"/><path d="M240.162 166.045c11.975-3.89 18.526-16.75 14.636-28.726-3.89-11.973-16.752-18.527-28.725-14.636L44.708 181.632c-11.187 4.046-17.473 16.13-14.135 27.73 3.483 12.099 16.334 19.475 28.217 15.614l181.372-58.93" fill="#CE1E5B"/><path d="M82.508 217.27l43.347-14.084-14.086-43.352-43.35 14.09 14.089 43.347" fill="#392538"/><path d="M173.847 187.591c16.388-5.323 31.62-10.273 43.348-14.084l-14.088-43.36-43.35 14.09 14.09 43.354" fill="#BB242A"/><path d="M210.484 74.706c11.974-3.89 18.527-16.751 14.637-28.727-3.89-11.973-16.752-18.526-28.727-14.636L15.028 90.293C3.842 94.337-2.445 106.422.896 118.022c3.481 12.098 16.332 19.474 28.217 15.613l181.371-58.93" fill="#72C5CD"/><path d="M52.822 125.933c11.805-3.836 27.025-8.782 43.354-14.086-5.323-16.39-10.273-31.622-14.084-43.352l-43.36 14.092 14.09 43.346" fill="#248C73"/><path d="M144.16 96.256l43.356-14.088a546179.21 546179.21 0 0 0-14.089-43.36L130.07 52.9l14.09 43.356" fill="#62803A"/></svg>
\ No newline at end of file
@charset "utf-8";
$primary: 'indigo';
@import "base/variables";
@import "base/colors";
@import "base/reset";
@import "base/mixins";
@import "base/fonts";
@import "base/base";
@import "libs/animate";
@import 'pages/login';
...@@ -9,23 +9,65 @@ ...@@ -9,23 +9,65 @@
justify-content: center; justify-content: center;
&-container { &-container {
position: relative;
display: flex; display: flex;
width: 650px; width: 450px;
align-items: stretch; align-items: stretch;
box-shadow: 0 14px 28px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22); box-shadow: 0 14px 28px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22);
&.is-expanded {
width: 650px;
}
@include until($tablet) {
width: 350px;
&.is-expanded {
width: 400px;
}
}
}
&-error {
position: absolute;
bottom: 100%;
width: 100%;
min-height: 50px;
background-image: radial-gradient(ellipse at top left, rgba(mc('red', '900'),.9) 0%,rgba(mc('red', '400'),.8) 100%);
border: 1px solid #FFF;
color: #FFF;
display: flex;
justify-content: center;
align-items: center;
strong {
font-weight: 600;
text-transform: uppercase;
display: block;
padding: 0 1rem 0 0;
border-right: 1px solid #FFF;
}
span {
padding: 0 0 0 1rem;
display: block;
}
} }
&-providers { &-providers {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 200px; width: 250px;
border: 1px solid #FFF; border: 1px solid #FFF;
background-color: mc('grey', '900'); background-color: mc('grey', '900');
z-index: 1; z-index: 1;
@include until($tablet) {
width: 50px;
}
button { button {
flex: 1 1; flex: 1 1;
padding: 0 15px; padding: 5px 15px;
border: none; border: none;
color: #FFF; color: #FFF;
background-color: mc('grey', '800'); background-color: mc('grey', '800');
...@@ -34,6 +76,18 @@ ...@@ -34,6 +76,18 @@
font-weight: 600; font-weight: 600;
text-align: left; text-align: left;
min-height: 40px; min-height: 40px;
display: flex;
justify-content: flex-start;
align-items: center;
transition: all .4s ease;
@include until($tablet) {
justify-content: center;
}
&:hover {
background-color: mc('grey', '600');
}
&:first-child { &:first-child {
border-top: none; border-top: none;
...@@ -48,10 +102,36 @@ ...@@ -48,10 +102,36 @@
i { i {
margin-right: 10px; margin-right: 10px;
font-size: 16px; font-size: 16px;
@include until($tablet) {
margin-right: 0;
font-size: 20px;
}
}
svg {
margin-right: 10px;
width: auto;
height: 20px;
max-width: 18px;
max-height: 20px;
path {
fill: #FFF;
}
@include until($tablet) {
margin-right: 0;
font-size: 20px;
}
} }
span { span {
font-weight: 600; font-weight: 600;
@include until($tablet) {
display: none;
}
} }
} }
} }
...@@ -59,7 +139,7 @@ ...@@ -59,7 +139,7 @@
&-frame { &-frame {
background-image: radial-gradient(circle at top left, rgba(255,255,255,1) 0%,rgba(240,240,240,.6) 100%); background-image: radial-gradient(circle at top left, rgba(255,255,255,1) 0%,rgba(240,240,240,.6) 100%);
border: 1px solid #FFF; border: 1px solid #FFF;
width: 450px; width: 400px;
padding: 1rem; padding: 1rem;
color: mc('grey', '700'); color: mc('grey', '700');
display: flex; display: flex;
...@@ -67,6 +147,10 @@ ...@@ -67,6 +147,10 @@
flex-direction: column; flex-direction: column;
text-align: center; text-align: center;
@include until($tablet) {
width: 350px;
}
h1 { h1 {
font-size: 2rem; font-size: 2rem;
font-weight: 600; font-weight: 600;
...@@ -83,29 +167,6 @@ ...@@ -83,29 +167,6 @@
margin: 0 0 25px 0; margin: 0 0 25px 0;
} }
h3 {
font-size: 1.25rem;
font-weight: normal;
color: #FB8C00;
padding: 0;
margin: 0;
animation: shake 1s ease;
> .fa {
margin-right: 7px;
}
}
h4 {
font-size: .8rem;
font-weight: normal;
color: rgba(255,255,255,0.7);
padding: 0;
margin: 0 0 15px 0;
animation: fadeIn 3s ease;
}
form { form {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
...@@ -147,14 +208,10 @@ ...@@ -147,14 +208,10 @@
font-weight: 400; font-weight: 400;
text-shadow: 1px 1px 0 #000; text-shadow: 1px 1px 0 #000;
.icon {
font-size: 1.2rem;
margin: 0 8px;
}
a { a {
font-weight: 600; font-weight: 600;
color: #FFF; color: #FFF;
margin-left: .25rem;
} }
} }
......
...@@ -8,24 +8,29 @@ ...@@ -8,24 +8,29 @@
const AzureAdOAuth2Strategy = require('passport-azure-ad-oauth2').Strategy const AzureAdOAuth2Strategy = require('passport-azure-ad-oauth2').Strategy
module.exports = (passport, conf) => { module.exports = {
const jwt = require('jsonwebtoken') key: 'azure',
passport.use('azure_ad_oauth2', title: 'Azure Active Directory',
new AzureAdOAuth2Strategy({ props: ['clientId', 'clientSecret', 'callbackURL', 'resource', 'tenant'],
clientID: conf.clientId, init (passport, conf) {
clientSecret: conf.clientSecret, const jwt = require('jsonwebtoken')
callbackURL: conf.callbackURL, passport.use('azure_ad_oauth2',
resource: conf.resource, new AzureAdOAuth2Strategy({
tenant: conf.tenant clientID: conf.clientId,
}, (accessToken, refreshToken, params, profile, cb) => { clientSecret: conf.clientSecret,
let waadProfile = jwt.decode(params.id_token) callbackURL: conf.callbackURL,
waadProfile.id = waadProfile.oid resource: conf.resource,
waadProfile.provider = 'azure' tenant: conf.tenant
wiki.db.User.processProfile(waadProfile).then((user) => { }, (accessToken, refreshToken, params, profile, cb) => {
return cb(null, user) || true let waadProfile = jwt.decode(params.id_token)
}).catch((err) => { waadProfile.id = waadProfile.oid
return cb(err, null) || true waadProfile.provider = 'azure'
}) wiki.db.User.processProfile(waadProfile).then((user) => {
} return cb(null, user) || true
)) }).catch((err) => {
return cb(err, null) || true
})
}
))
}
} }
...@@ -8,19 +8,24 @@ ...@@ -8,19 +8,24 @@
const FacebookStrategy = require('passport-facebook').Strategy const FacebookStrategy = require('passport-facebook').Strategy
module.exports = (passport, conf) => { module.exports = {
passport.use('facebook', key: 'facebook',
new FacebookStrategy({ title: 'Facebook',
clientID: conf.clientId, props: ['clientId', 'clientSecret', 'callbackURL'],
clientSecret: conf.clientSecret, init (passport, conf) {
callbackURL: conf.callbackURL, passport.use('facebook',
profileFields: ['id', 'displayName', 'email'] new FacebookStrategy({
}, function (accessToken, refreshToken, profile, cb) { clientID: conf.clientId,
wiki.db.User.processProfile(profile).then((user) => { clientSecret: conf.clientSecret,
return cb(null, user) || true callbackURL: conf.callbackURL,
}).catch((err) => { profileFields: ['id', 'displayName', 'email']
return cb(err, null) || true }, function (accessToken, refreshToken, profile, cb) {
}) wiki.db.User.processProfile(profile).then((user) => {
} return cb(null, user) || true
)) }).catch((err) => {
return cb(err, null) || true
})
}
))
}
} }
...@@ -8,19 +8,24 @@ ...@@ -8,19 +8,24 @@
const GitHubStrategy = require('passport-github2').Strategy const GitHubStrategy = require('passport-github2').Strategy
module.exports = (passport, conf) => { module.exports = {
passport.use('github', key: 'github',
new GitHubStrategy({ title: 'GitHub',
clientID: conf.clientId, props: ['clientId', 'clientSecret', 'callbackURL'],
clientSecret: conf.clientSecret, init (passport, conf) {
callbackURL: conf.callbackURL, passport.use('github',
scope: ['user:email'] new GitHubStrategy({
}, (accessToken, refreshToken, profile, cb) => { clientID: conf.clientId,
wiki.db.User.processProfile(profile).then((user) => { clientSecret: conf.clientSecret,
return cb(null, user) || true callbackURL: conf.callbackURL,
}).catch((err) => { scope: ['user:email']
return cb(err, null) || true }, (accessToken, refreshToken, profile, cb) => {
}) wiki.db.User.processProfile(profile).then((user) => {
} return cb(null, user) || true
)) }).catch((err) => {
return cb(err, null) || true
})
}
))
}
} }
...@@ -8,18 +8,23 @@ ...@@ -8,18 +8,23 @@
const GoogleStrategy = require('passport-google-oauth20').Strategy const GoogleStrategy = require('passport-google-oauth20').Strategy
module.exports = (passport, conf) => { module.exports = {
passport.use('google', key: 'google',
new GoogleStrategy({ title: 'Google ID',
clientID: conf.clientId, props: ['clientId', 'clientSecret', 'callbackURL'],
clientSecret: conf.clientSecret, init (passport, conf) {
callbackURL: conf.callbackURL passport.use('google',
}, (accessToken, refreshToken, profile, cb) => { new GoogleStrategy({
wiki.db.User.processProfile(profile).then((user) => { clientID: conf.clientId,
return cb(null, user) || true clientSecret: conf.clientSecret,
}).catch((err) => { callbackURL: conf.callbackURL
return cb(err, null) || true }, (accessToken, refreshToken, profile, cb) => {
}) wiki.db.User.processProfile(profile).then((user) => {
} return cb(null, user) || true
)) }).catch((err) => {
return cb(err, null) || true
})
}
))
}
} }
...@@ -9,32 +9,37 @@ ...@@ -9,32 +9,37 @@
const LdapStrategy = require('passport-ldapauth').Strategy const LdapStrategy = require('passport-ldapauth').Strategy
const fs = require('fs') const fs = require('fs')
module.exports = (passport, conf) => { module.exports = {
passport.use('ldapauth', key: 'ldap',
new LdapStrategy({ title: 'LDAP / Active Directory',
server: { props: ['url', 'bindDn', 'bindCredentials', 'searchBase', 'searchFilter', 'tlsEnabled', 'tlsCertPath'],
url: conf.url, init (passport, conf) {
bindDn: conf.bindDn, passport.use('ldapauth',
bindCredentials: conf.bindCredentials, new LdapStrategy({
searchBase: conf.searchBase, server: {
searchFilter: conf.searchFilter, url: conf.url,
searchAttributes: ['displayName', 'name', 'cn', 'mail'], bindDn: conf.bindDn,
tlsOptions: (conf.tlsEnabled) ? { bindCredentials: conf.bindCredentials,
ca: [ searchBase: conf.searchBase,
fs.readFileSync(conf.tlsCertPath) searchFilter: conf.searchFilter,
] searchAttributes: ['displayName', 'name', 'cn', 'mail'],
} : {} tlsOptions: (conf.tlsEnabled) ? {
}, ca: [
usernameField: 'email', fs.readFileSync(conf.tlsCertPath)
passReqToCallback: false ]
}, (profile, cb) => { } : {}
profile.provider = 'ldap' },
profile.id = profile.dn usernameField: 'email',
wiki.db.User.processProfile(profile).then((user) => { passReqToCallback: false
return cb(null, user) || true }, (profile, cb) => {
}).catch((err) => { profile.provider = 'ldap'
return cb(err, null) || true profile.id = profile.dn
}) wiki.db.User.processProfile(profile).then((user) => {
} return cb(null, user) || true
)) }).catch((err) => {
return cb(err, null) || true
})
}
))
}
} }
...@@ -8,25 +8,30 @@ ...@@ -8,25 +8,30 @@
const LocalStrategy = require('passport-local').Strategy const LocalStrategy = require('passport-local').Strategy
module.exports = (passport, conf) => { module.exports = {
passport.use('local', key: 'local',
new LocalStrategy({ title: 'Local',
usernameField: 'email', props: [],
passwordField: 'password' init (passport, conf) {
}, (uEmail, uPassword, done) => { passport.use('local',
wiki.db.User.findOne({ email: uEmail, provider: 'local' }).then((user) => { new LocalStrategy({
if (user) { usernameField: 'email',
return user.validatePassword(uPassword).then(() => { passwordField: 'password'
return done(null, user) || true }, (uEmail, uPassword, done) => {
}).catch((err) => { wiki.db.User.findOne({ email: uEmail, provider: 'local' }).then((user) => {
return done(err, null) if (user) {
}) return user.validatePassword(uPassword).then(() => {
} else { return done(null, user) || true
return done(new Error('INVALID_LOGIN'), null) }).catch((err) => {
} return done(err, null)
}).catch((err) => { })
done(err, null) } else {
}) return done(new Error('INVALID_LOGIN'), null)
} }
)) }).catch((err) => {
done(err, null)
})
}
))
}
} }
...@@ -8,18 +8,23 @@ ...@@ -8,18 +8,23 @@
const WindowsLiveStrategy = require('passport-windowslive').Strategy const WindowsLiveStrategy = require('passport-windowslive').Strategy
module.exports = (passport, conf) => { module.exports = {
passport.use('windowslive', key: 'microsoft',
new WindowsLiveStrategy({ title: 'Microsoft Account',
clientID: conf.clientId, props: ['clientId', 'clientSecret', 'callbackURL'],
clientSecret: conf.clientSecret, init (passport, conf) {
callbackURL: conf.callbackURL passport.use('windowslive',
}, function (accessToken, refreshToken, profile, cb) { new WindowsLiveStrategy({
wiki.db.User.processProfile(profile).then((user) => { clientID: conf.clientId,
return cb(null, user) || true clientSecret: conf.clientSecret,
}).catch((err) => { callbackURL: conf.callbackURL
return cb(err, null) || true }, function (accessToken, refreshToken, profile, cb) {
}) wiki.db.User.processProfile(profile).then((user) => {
} return cb(null, user) || true
)) }).catch((err) => {
return cb(err, null) || true
})
}
))
}
} }
...@@ -8,18 +8,23 @@ ...@@ -8,18 +8,23 @@
const SlackStrategy = require('passport-slack').Strategy const SlackStrategy = require('passport-slack').Strategy
module.exports = (passport, conf) => { module.exports = {
passport.use('slack', key: 'slack',
new SlackStrategy({ title: 'Slack',
clientID: conf.clientId, props: ['clientId', 'clientSecret', 'callbackURL'],
clientSecret: conf.clientSecret, init (passport, conf) {
callbackURL: conf.callbackURL passport.use('slack',
}, (accessToken, refreshToken, profile, cb) => { new SlackStrategy({
wiki.db.User.processProfile(profile).then((user) => { clientID: conf.clientId,
return cb(null, user) || true clientSecret: conf.clientSecret,
}).catch((err) => { callbackURL: conf.callbackURL
return cb(err, null) || true }, (accessToken, refreshToken, profile, cb) => {
}) wiki.db.User.processProfile(profile).then((user) => {
} return cb(null, user) || true
)) }).catch((err) => {
return cb(err, null) || true
})
}
))
}
} }
...@@ -37,7 +37,8 @@ const bruteforce = new ExpressBrute(EBstore, { ...@@ -37,7 +37,8 @@ const bruteforce = new ExpressBrute(EBstore, {
*/ */
router.get('/login', function (req, res, next) { router.get('/login', function (req, res, next) {
res.render('auth/login', { res.render('auth/login', {
usr: res.locals.usr authStrategies: wiki.auth.strategies,
hasMultipleStrategies: Object.keys(wiki.config.auth.strategies).length > 0
}) })
}) })
......
...@@ -16,6 +16,7 @@ module.exports = Promise.join( ...@@ -16,6 +16,7 @@ module.exports = Promise.join(
// Load global modules // Load global modules
// ---------------------------------------- // ----------------------------------------
wiki.auth = require('./modules/auth').init()
wiki.disk = require('./modules/disk').init() wiki.disk = require('./modules/disk').init()
wiki.docs = require('./modules/documents').init() wiki.docs = require('./modules/documents').init()
wiki.git = require('./modules/git').init(false) wiki.git = require('./modules/git').init(false)
...@@ -38,7 +39,6 @@ module.exports = Promise.join( ...@@ -38,7 +39,6 @@ module.exports = Promise.join(
const http = require('http') const http = require('http')
const i18nBackend = require('i18next-node-fs-backend') const i18nBackend = require('i18next-node-fs-backend')
const path = require('path') const path = require('path')
const passport = require('passport')
const passportSocketIo = require('passport.socketio') const passportSocketIo = require('passport.socketio')
const session = require('express-session') const session = require('express-session')
const SessionRedisStore = require('connect-redis')(session) const SessionRedisStore = require('connect-redis')(session)
...@@ -78,10 +78,6 @@ module.exports = Promise.join( ...@@ -78,10 +78,6 @@ module.exports = Promise.join(
// Passport Authentication // Passport Authentication
// ---------------------------------------- // ----------------------------------------
require('./modules/auth').init(passport)
wiki.rights = require('./modules/rights')
// wiki.rights.init()
let sessionStore = new SessionRedisStore({ let sessionStore = new SessionRedisStore({
client: wiki.redis client: wiki.redis
}) })
...@@ -95,8 +91,8 @@ module.exports = Promise.join( ...@@ -95,8 +91,8 @@ module.exports = Promise.join(
saveUninitialized: false saveUninitialized: false
})) }))
app.use(flash()) app.use(flash())
app.use(passport.initialize()) app.use(wiki.auth.passport.initialize())
app.use(passport.session()) app.use(wiki.auth.passport.session())
// ---------------------------------------- // ----------------------------------------
// SEO // SEO
...@@ -135,6 +131,7 @@ module.exports = Promise.join( ...@@ -135,6 +131,7 @@ module.exports = Promise.join(
// View accessible data // View accessible data
// ---------------------------------------- // ----------------------------------------
app.locals.basedir = wiki.ROOTPATH
app.locals._ = require('lodash') app.locals._ = require('lodash')
app.locals.t = wiki.lang.t.bind(wiki.lang) app.locals.t = wiki.lang.t.bind(wiki.lang)
app.locals.moment = require('moment') app.locals.moment = require('moment')
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* @return {any} void * @return {any} void
*/ */
module.exports = (req, res, next) => { module.exports = (req, res, next) => {
res.locals.appflash = req.flash('alert') res.locals.flash = req.flash('alert')
next() next()
} }
...@@ -3,10 +3,16 @@ ...@@ -3,10 +3,16 @@
/* global wiki */ /* global wiki */
const _ = require('lodash') const _ = require('lodash')
const passport = require('passport')
const fs = require('fs-extra')
const path = require('path')
module.exports = { module.exports = {
init(passport) { strategies: {},
// Serialization user methods init() {
this.passport = passport
// Serialization user methods
passport.serializeUser(function (user, done) { passport.serializeUser(function (user, done) {
done(null, user._id) done(null, user._id)
...@@ -27,20 +33,26 @@ module.exports = { ...@@ -27,20 +33,26 @@ module.exports = {
// Load authentication strategies // Load authentication strategies
wiki.config.authStrategies = { _.forOwn(wiki.config.auth.strategies, (strategyConfig, strategyKey) => {
list: _.pickBy(wiki.config.auth, strategy => strategy.enabled), strategyConfig.callbackURL = `${wiki.config.site.host}${wiki.config.site.path}/login/${strategyKey}/callback`
socialEnabled: (_.chain(wiki.config.auth).omit('local').filter(['enabled', true]).value().length > 0) let strategy = require(`../authentication/${strategyKey}`)
} strategy.init(passport, strategyConfig)
fs.readFile(path.join(wiki.ROOTPATH, `assets/svg/auth-icon-${strategyKey}.svg`), 'utf8').then(iconData => {
_.forOwn(wiki.config.authStrategies.list, (strategyConfig, strategyName) => { strategy.icon = iconData
strategyConfig.callbackURL = `${wiki.config.site.host}/login/${strategyName}/callback` }).catch(err => {
require(`../authentication/${strategyName}`)(passport, strategyConfig) if (err.code === 'ENOENT') {
wiki.logger.info(`Authentication Provider ${_.upperFirst(strategyName)}: OK`) strategy.icon = '[missing icon]'
} else {
wiki.logger.error(err)
}
})
this.strategies[strategy.key] = strategy
wiki.logger.info(`Authentication Provider ${strategyKey}: OK`)
}) })
// Create Guest account for first-time // Create Guest account for first-time
return wiki.db.User.findOne({ wiki.db.User.findOne({
where: { where: {
provider: 'local', provider: 'local',
email: 'guest@example.com' email: 'guest@example.com'
...@@ -88,5 +100,7 @@ module.exports = { ...@@ -88,5 +100,7 @@ module.exports = {
// }) // })
// } else { return true } // } else { return true }
// }) // })
return this
} }
} }
...@@ -3,52 +3,30 @@ extends ../master.pug ...@@ -3,52 +3,30 @@ extends ../master.pug
block body block body
body body
.login#root .login#root
.login-container .login-container(:class={ "is-expanded": hasMultipleStrategies })
if config.authStrategies.socialEnabled if flash.length > 0
.login-error
strong
i.icon-warning-outline
= flash[0].title
span= flash[0].message
if hasMultipleStrategies
.login-providers .login-providers
button.is-active(onclick='window.location.assign("/login/ms")') button.is-active(title=t('auth:providers.local'))
i.nc-icon-outline.ui-1_database i.nc-icon-outline.ui-1_database
span= t('auth:providers.local') span= t('auth:providers.local')
if config.auth.microsoft && config.auth.microsoft.enabled each strategy in authStrategies
button(onclick='window.location.assign("/login/ms")') button(onclick='window.location.assign("/login/' + strategy.key + '")', title=strategy.title)
i.icon-windows2 != strategy.icon
span= t('auth:providers.windowslive') span= strategy.title
if config.auth.azure && config.auth.azure.enabled
button(onclick='window.location.assign("/login/azure")')
i.icon-windows2
span= t('auth:providers.azure')
if config.auth.google && config.auth.google.enabled
button(onclick='window.location.assign("/login/google")')
i.icon-google
span= t('auth:providers.google')
if config.auth.facebook && config.auth.facebook.enabled
button(onclick='window.location.assign("/login/facebook")')
i.icon-facebook
span= t('auth:providers.facebook')
if config.auth.github && config.auth.github.enabled
button(onclick='window.location.assign("/login/github")')
i.icon-github
span= t('auth:providers.github')
if config.auth.slack && config.auth.slack.enabled
button(onclick='window.location.assign("/login/slack")')
i.icon-slack
span= t('auth:providers.slack')
.login-frame .login-frame
h1= config.site.title h1= config.site.title
h2= t('auth:loginrequired') h2= t('auth:loginrequired')
if appflash.length > 0 form(method='post', action='/login')
h3 input#login-user(type='text', name='email', placeholder=t('auth:fields.emailuser'))
i.icon-warning-outline input#login-pass(type='password', name='password', placeholder=t('auth:fields.password'))
= appflash[0].title button.button.is-light-green.is-fullwidth(type='submit')
h4= appflash[0].message span= t('auth:actions.login')
if config.auth.local.enabled
form(method='post', action='/login')
input#login-user(type='text', name='email', placeholder=t('auth:fields.emailuser'))
input#login-pass(type='password', name='password', placeholder=t('auth:fields.password'))
button.button.is-light-green.is-fullwidth(type='submit')
span= t('auth:actions.login')
.login-copyright .login-copyright
= t('footer.poweredby') + ' ' = t('footer.poweredby')
a.icon(href='https://github.com/Requarks/wiki') a(href='https://wiki.js.org', rel='external', title='Wiki.js') Wiki.js
i.icon-github
a(href='https://wiki.requarks.io/') Wiki.js
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment