File manager - Edit - /home/opticamezl/www/newok/531c5/plg_system_webauthn.tar
Back
images/fido.png 0000644 00000006655 15172624222 0007457 0 ustar 00 �PNG IHDR �� pHYs .# .#x�?v OiCCPPhotoshop ICC profile xڝSgTS�=���BK���KoR RB���&*! J�!��Q�EEȠ�����Q,� ��!��������{�kּ�����>�����H3Q5��B������.@� $p �d!s�# �~<<+"�� x� �M��0���B�\���t�8K� @z�B� @F���&S � `�cb� P- `'�� ����{ [�!�� e�D h; ��V�E X0 fK�9 �- 0IWfH �� ��� 0Q��) { `�##x �� F�W<�+��* x��<�$9E�[-qWW.(�I+6aa�@.�y�2�4��� ����x����6��_-��"bb��ϫp@ �t~�,/��;�m��%�h^�u��f�@� ���W�p�~<<E���������J�B[a�W}�g�_�W�l�~<�����$�2]�G�����L�ϒ �b��G�����"�Ib�X*�Qq�D���2�"�B�)�%�d��,�>�5 �j>{�-�]c�K'Xt�� �o��(�h���w��?�G�% �fI�q ^D$.Tʳ?� D��*�A�,����`6�B$��BB d�r`)��B(�Ͱ*`/�@4�Qh��p.�U�=p�a��(�� A�a!ڈb�X#����!�H�$ ɈQ"K�5H1R�T UH�=r9�\F��;� 2����G1���Q=��C��7�F��dt1�����r�=�6��Ыhڏ>C�0��3�l0.��B�8, �c˱"����V����cϱw�E� 6wB aAHXLXN�H� $4� 7 �Q�'"��K�&���b21�XH,#��/{�C�7$�C2'��I��T��F�nR#�,��4H#���dk�9�, +ȅ����3��!�[ �b@q��S�(R�jJ��4�e�2AU��Rݨ�T5�ZB���R�Q��4u�9̓IK�����hh�i��t�ݕN��W���G���w ��Ljg(�gw��L�Ӌ�T071���oUX*�*|�� �J�&�*/T����ުU�U�T��^S}�FU3S� Ԗ�U��P�SSg�;���g�oT?�~Y��Y�L�OC�Q��_�� c�x,!k ��u�5�&���|v*�����=���9C3J3W�R�f?�q��tN �(���~���)�)�4L�1e\k����X�H�Q�G�6����E�Y��A�J'\'Gg����S�Sݧ �M=:��.�k���Dw�n��^��Lo��y��}/�T�m���GX�$��<�5qo</���QC]�@C�a�a�ᄑ��<��F�F�i�\�$�m�mƣ&&!&KM�M�RM��)�;L;L���͢�֙5�=1�2��כ߷`ZxZ,����eI��Z�Yn�Z9Y�XUZ]�F���%ֻ�����N�N���gð�ɶ�����ۮ�m�}agbg�Ů��}�}��= ���Z~s�r:V:ޚΜ�?}���/gX���3��)�i�S��Ggg�s�K��.�>.���Ƚ�Jt�q]�z�������ۯ�6�i�ܟ�4�)�Y3s���C�Q��?��0k߬~OCO�g��#/c/�W�װ��w��a�>�>r��>�<7�2�Y_�7��ȷ�O�o�_��C#�d�z�� ��%g��A�[��z|!��?:�e����A���AA�����!h�쐭!��Α�i�P~���a�a��~'���W�?�p�X�1�5w��Cs�D�D�Dޛg1O9�-J5*>�.j<�7�4�?�.fY��X�XIlK9.*�6nl�������{�/�]py�����.,:�@L�N8��A*��%�w%� y��g"/�6ш�C\*N�H*Mz�쑼5y$�3�,幄'���L Lݛ:��v m2=:�1����qB�!M��g�g�fvˬe����n��/��k���Y- �B��TZ(�*�geWf�͉�9���+��̳�ې7����ᒶ��KW-X潬j9�<qy� �+�V�<���*m�O��W��~�&zMk�^�ʂ��k�U �}����]OX/Yߵa���>������(�x��oʿ�ܔ���Ĺd�f�f���-�[����n �ڴ �V��E�/��(ۻ��C���<��e����;?T�T�T�T6��ݵa�n��{��4���[���>ɾ�UUM�f�e�I���?�����m]�Nmq����#����=TR��+�G�����w- 6 U����#pDy�� � :�v�{���vg/jB��F�S��[b[�O�>����z�G��4<YyJ�T�i��ӓg�ό���}~.��`ۢ�{�c��jo�t��E���;�;�\�t���W�W��:_m�t�<���Oǻ�����\k��z��{f���7���y���՞9=ݽ�zo�����~r'��˻�w'O�_�@�A�C݇�?[�����j�w����G�������C���ˆ ��8>99�?r��C�d�&����ˮ/~�����јѡ�m|�����������x31^�V��w�w��O�| (�h���SЧ�������c3-� cHRM z% �� �� �� u0 �` :� o�_�F �IDATx���K�Qǿ�6״�s��$��%�b��"KFSK� -W������"� ��9SlR���d� K��96pc���k���f� ���}/x���|8��9����� � �~�e��u�a�j�? ��jkmUYq�b��)--7�,3�{���?�Β?i�b68ʨt:�w����� ŅE{�.j ���G`dh�w���r�������j||��K�K�������sh�*)��k8,�����gfd0))�+��p���j�(** x�j?|d2�VЊںZmA���E��6_ � w뻻� H@���%�T��e���։ BH�-�S� �C ���W���(�z���|(�8�ٓ� �z ,���<��������8=5 @w�!��t��(��n�l�3qqq�BAQ$&J$�X,���r�T*�2��NW)����d���盚�P^Q@�Rjx����>����G�@����Nf�E����w�w860�P p:]�|�@���(��yMoy��/��A���n���� �])�u����������>����͍�TH$�H�8�p���P*����b��olyQu� ����z�У��TR���|>���ؘH$�>��gyy���D��k_��ݛBʲkV�5B�WV�^��7���f��*���b�� �s ��6��=J� IEND�B`� images/webauthn.svg 0000644 00000006365 15172624222 0010364 0 ustar 00 <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="2.5em"><path fill="currentColor" d="M15.287 3.63a8.407 8.407 0 00-8.051 7.593h.55a7.805 7.805 0 012.24-4.713 5.825 5.825 0 00.924.695c-.608 1.177-.98 2.556-1.082 4.018h.135c.105-1.467.485-2.819 1.065-3.947.745.434 1.623.754 2.577.94a27.83 27.83 0 00-.25 3.763h-.847v.135h.847c.003 1.334.09 2.617.25 3.764-.954.185-1.832.506-2.577.94a9.997 9.997 0 01-.978-3.137h-.137c.164 1.16.502 2.25.997 3.208a5.825 5.825 0 00-.924.695 7.805 7.805 0 01-2.255-4.875H7.22A8.407 8.407 0 0024 12.034a8.398 8.398 0 00-.688-3.333 8.407 8.407 0 00-8.025-5.072zm.315.546c.155 0 .31.005.464.014.365.34.708 1.07.983 2.114a16.518 16.518 0 01.357 1.79 10.173 10.173 0 01-1.804.16 10.173 10.173 0 01-1.805-.16 16.519 16.519 0 01.357-1.79c.275-1.045.618-1.775.983-2.114a7.97 7.97 0 01.465-.014zm-.665.028c-.345.392-.658 1.093-.913 2.065a16.639 16.639 0 00-.36 1.8c-.939-.183-1.802-.498-2.533-.926.686-1.283 1.635-2.264 2.73-2.775a7.874 7.874 0 011.076-.164zm1.33 0a7.856 7.856 0 011.084.168c1.092.513 2.037 1.492 2.721 2.771-.73.428-1.594.743-2.533.927a16.64 16.64 0 00-.36-1.8c-.255-.972-.568-1.673-.912-2.066zm-2.972.314c-.655.407-1.257.989-1.776 1.73a8.166 8.166 0 00-.506.825 5.69 5.69 0 01-.891-.67 7.814 7.814 0 013.173-1.885zm4.624.006a7.862 7.862 0 013.164 1.877 5.692 5.692 0 01-.893.672 8.166 8.166 0 00-.506-.825c-.516-.738-1.115-1.318-1.765-1.724zm3.26 1.985a7.858 7.858 0 011.638 2.419 7.802 7.802 0 01.642 3.051h-2.095c-.01-1.74-.398-3.396-1.11-4.774a5.823 5.823 0 00.925-.696zm-1.044.767c.679 1.32 1.084 2.945 1.094 4.703h-3.42a27.863 27.863 0 00-.251-3.763c.954-.186 1.833-.506 2.577-.94zm-6.357.965a10.299 10.299 0 001.824.16 10.299 10.299 0 001.823-.16c.16 1.138.246 2.413.249 3.738h-1.178a1.03 1.03 0 01-.093.135h1.27a27.71 27.71 0 01-.248 3.739 10.397 10.397 0 00-3.647 0 27.733 27.733 0 01-.248-3.739h1.294a.99.99 0 01-.09-.135H13.53c.003-1.325.088-2.6.248-3.738zM2.558 9.37a2.585 2.585 0 00-2.547 2.35c-.142 1.541 1.064 2.842 2.566 2.842 1.26 0 2.312-.917 2.533-2.124h4.44v.972h.946v-.972h.837v1.431h.945v-2.376H5.11A2.586 2.586 0 002.558 9.37zm-.058.965a1.639 1.639 0 011.707 1.637 1.64 1.64 0 01-1.639 1.638 1.639 1.639 0 01-.068-3.275zm13.09.388a.75.75 0 00-.345 1.404l-.383 1.958h1.5l-.383-1.958a.75.75 0 00.384-.654.75.75 0 00-.773-.75zm2.218 1.391h3.421c-.01 1.758-.415 3.384-1.094 4.704-.744-.434-1.623-.755-2.577-.94a27.81 27.81 0 00.25-3.764zm3.556 0h2.095a7.805 7.805 0 01-2.281 5.47 5.825 5.825 0 00-.924-.696c.712-1.378 1.1-3.033 1.11-4.774zm-5.52 3.703a10.284 10.284 0 011.562.156 16.518 16.518 0 01-.357 1.791c-.275 1.045-.618 1.774-.982 2.114a7.972 7.972 0 01-.93 0c-.365-.34-.708-1.07-.983-2.114a16.519 16.519 0 01-.357-1.79 10.284 10.284 0 012.048-.157zm1.695.181c.94.184 1.803.5 2.533.926-.686 1.284-1.635 2.265-2.73 2.776a7.874 7.874 0 01-1.075.164c.344-.393.657-1.094.913-2.065a16.64 16.64 0 00.359-1.8zm-3.874 0a16.648 16.648 0 00.359 1.8c.255.973.568 1.674.913 2.066a7.873 7.873 0 01-1.075-.164c-1.096-.511-2.045-1.492-2.731-2.775.73-.428 1.594-.743 2.534-.927zm-2.652.997a8.16 8.16 0 00.506.825c.52.741 1.121 1.323 1.776 1.73a7.814 7.814 0 01-3.174-1.884 5.694 5.694 0 01.892-.67zm9.178 0a5.694 5.694 0 01.891.67 7.814 7.814 0 01-3.173 1.885c.654-.407 1.256-.989 1.775-1.73a8.16 8.16 0 00.507-.825z"></path></svg> js/login-es5.min.js.gz 0000644 00000003006 15172624222 0010523 0 ustar 00 � �V[o�6~�` � k�I�m�qY�y��� �d�-�lhR#)����>P��I���%��|<�΅,J�e �.= �J�y� �A?2��9�����+-��.se�S_� ������2,�y���b�T�!rF���� �&�t)�8��Ȥ}������f��ۀ��?4��J��̇�-� ��誜k����x �+k�{d�2� ��Gg��d�ç� �9�(�� oo%}��OU�}j$�i��m�N�<1,�*!�Ve��#A`LQ� �B����4�{�zb(_X7����Ԃ�mv��L_lL+�5�<,��]_��,����fp{=:���0� �c��ϜD�4y�*�>�{�*���f��o�hM��Y�OX��67��]��N@C�;՚�����;�&�Ժf��ݔZԂ�6tg�$��t`�P� L�J���`,W�����[�� ���V�S|xa� ���v i���D%��|���U��;5m\� �}̺��^0=� �$w`2p��� ��.�3Ӛ�l�H9K���<XI&�)���tg6.�Bo�f)��{d�^�r��)���G9�}L$�(9i��k�uL�nȬ��hX:�A6h�<2k�Uv��7��LQ4����t��?&Gʣ��q�� ��Ep+e 2˔���E�q�ܒo�j�?Ze��'<]J��R"� | |F��������b����ۛ_dz�l4���|���v2��^1�����U&|��oM�V"��G�RvX�:� �Ӝr+�p��ݜ9�%���S�x*�+Y�gc��?pF�C�L�O BM)3r�r�������!���Ԕ�%�G��2�T�Ġ,��x�ǜ܌�$���x ��R��xH�8fb�4b�Y��Y�ΟhS�R�������r���cUJ�W���t��^�RVzp�J��xٽƃ��%Gj��]�fJȘ��"���� \Ȱ����6�QAu�x��>>R&�O�X8�L�17r�� �?��z��ރ�q̼���D�v5��^�lY�H�h��z��Q������ #���2�f�(��r��^&���4��u�6��K)�)Oe�l��$Ξz y��v%����<t:��Ј<^�?mG�q�.�aX��t�!��SLc��촭�i;!�|>l�_��݁�N��˛�/��a�֔�~� ���R���p'����Fc3��cxqu�����Z$xG�$#1k���0ky�`'7�혐�}��lLJNg��X{�[�[�ݗ):-D�r����| U�tB������|u9��,<�E�5�2M��d�ϲ�g!�zܶ*DS�tHI�U�&��5�<=�NI�}���}�p������Mv��n�}ܭy*�&�3�O��Y����gM���e��Ѹ�V�^o�t���\f�p &�+��Np�Uz��Ӎ��tq���.��ł&!��4��e �cR��0�m���hM��e6-c�Ӛ:x�/��4� js/management-es5.min.js.gz 0000644 00000004603 15172624222 0011533 0 ustar 00 � �Yms۸�~��F�"�a;s�t��TG��m,�Ҏǣ���x (Y��$ʒ}�%����],v�]@�8W�Z�x�r�uF���_��.x�#��g�B�ﵞJNod� U��|�&�/��)�È�n��K�Xg#҉� ������:�unb.�s`, �UL��O��lt|<���J�6�%/)bP�R��Շ�(0\7�H�8���g`��*xhH�\�w{W�u����\�D�i�+���eA֦qd��3n�>[�*�c3-��� �!�۞�3��\nTp=����aaC��X��'ᚻ�K1�"=ĝ�?`H�k^r*A�n���j!L�P�:����unϻz�iʅ"���x�8ڿ �!�ۻ���a���+�U9H,.0�� �tԀJ�\��<.�m�;q_��h&�ʋ>�Nt�����PNpiY�g�8<Q��DB��Dʝ6�����a�n.� ���z�Ï�7g?] {��ë���������v��}�ް?g�M�]g^"[�@���"L�7I�:����Ct,T4�d(��M���ŧ�w�K���t�?�DR��,� ��1�U�!2�f�]�>Y��y\�J��4!"� ��TE���S�?�B���o�_r�.\�FF�L�Mt��� ��;�C�D�~�`m��kge���}E3n,��;�S .b��ɲ��Y������{�;��EA��G�ԨZjw�=D:\u<{\� /Qm〪��@��#�� �F���LFN��P)=�N���(�2��g�ĸ vk�WS3I d���"���c�I�t ;��-�a\�Y�;�nb�<P0J��\�EI_<8WY��ٿ~�Y&��n��h����� f*O�{"�և��83�/¿Ř~�B��!\Ԧ�E[�x¥��P�o%}i��6,wzڰA����ڰ���<sቇ/Es���Y�k�s��X�IӟZ�p�0�7H�<�J�EmXj�Ps�UrGMS`L�8J K+0 �Y�t� �H�� �-���I�I����"C��>?O"�ިZN`L�L+�2��{���wMMK�I1&����-��r��w�+�*,6|ބ�]. J-�D�*X�x�0n�/�h��z/D��1�lL�,� !vڜI�?e2V{��v4劧0厄r`�<�=H�� K�N���s�����]p)~�o�w0�Z:��p/����&��1�2�lygϧ��p�K���#��+��=�di����S�\#�"!��=Ƕ.�/�G�)&����{���;�/A~w�(wN+�I�bO���O��B)0ި$a�j%C����ƒ[{ŧ�Ю���y��%<)ώ^��b�vy �Eng%j0��!�QU����|7�1ϥ���dM| �Z9�e%g�+g���t�|�UG� ��=Ed�1{�.�<�:{��\ �g?��goz��Iқ�r�:� Q,E��Fe�����|� |�_M,�A���l��3�ͻ�q�% ��r*��7���^hV���Ӷ/#��r�* �l��B�䀊�c'��K���,�W׃�h��q[�x��x���(@��&, ��:�n�i@r��GvpJҭ�iAN���7��ys�U f�̳?��ݳ�n�b�γ���N^�[R�(3 B$�.��;2 3�h`�x`�94�%�dK�I)vORxle��a=�j,̴�+��]\�9�v��~<����]��{ �qp�?�(�>���RI̴O%9�w���x��[GѮ���&�%�9��Z� ��@Z�Ғ Ҳ�eMHKV���dibf%���<U��m�2��L��h�p/��x+���5Y�a����>y�� {�%?�v��QW�@�]?�)�~[k��c*���j>ѩ=Ot�L݉{�ْ+1-�.�nw�����&�nw���$ �"Z~;�7:!7�P��TOm� �����M�S8#ҴY�:�V�&z&�8�����#���Н�Ξ����t�n��fgӌ| �2�қ�,"N8 ^/����!���i�'+o�M����kï�ͪ��4��W�U��G�iv� d:�t=t��f���-�6�le����&@L3��\R�:l3�i��z�fI���L��-k\����m[?״ZO���o�26�QGTh�������$�V]�з�ߊ/���*����OƼ�(|��=�?���{ရ~>���͋�nn»�6��V��y��/�G<In�VK=]�={���I���ИK���}F H���G��R�"*�m|�� ��E�(|��u-�q֪�7Puˍ����GV�:�D�y "q��� ���� js/management.js 0000644 00000035214 15172624222 0007642 0 ustar 00 /** * @package Joomla.Plugin * @subpackage System.webauthn * * @copyright (C) 2020 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ window.Joomla = window.Joomla || {}; ((Joomla, document) => { /** * Converts a simple object containing query string parameters to a single, escaped query string. * This method is a necessary evil since Joomla.request can only accept data as a string. * * @param object {object} A plain object containing the query parameters to pass * @param prefix {string} Prefix for array-type parameters * * @returns {string} */ const interpolateParameters = (object, prefix = '') => { let encodedString = ''; Object.keys(object).forEach(prop => { if (typeof object[prop] !== 'object') { if (encodedString.length > 0) { encodedString += '&'; } if (prefix === '') { encodedString += `${encodeURIComponent(prop)}=${encodeURIComponent(object[prop])}`; } else { encodedString += `${encodeURIComponent(prefix)}[${encodeURIComponent(prop)}]=${encodeURIComponent(object[prop])}`; } return; } // Objects need special handling encodedString += `${interpolateParameters(object[prop], prop)}`; }); return encodedString; }; /** * A simple error handler * * @param {String} message */ const handleCreationError = message => { Joomla.renderMessages({ error: [message] }); }; /** * Ask the user to link an authenticator using the provided public key (created server-side). * Posts the credentials to the URL defined in post_url using AJAX. * That URL must re-render the management interface. * These contents will replace the element identified by the interface_selector CSS selector. */ // eslint-disable-next-line no-unused-vars Joomla.plgSystemWebauthnInitCreateCredentials = () => { // Make sure the browser supports Webauthn if (!('credentials' in navigator)) { Joomla.renderMessages({ error: [Joomla.Text._('PLG_SYSTEM_WEBAUTHN_ERR_NO_BROWSER_SUPPORT')] }); return; } // Get the public key creation options through AJAX. const paths = Joomla.getOptions('system.paths'); const postURL = `${paths ? `${paths.base}/index.php` : window.location.pathname}`; const postBackData = { option: 'com_ajax', group: 'system', plugin: 'webauthn', format: 'json', akaction: 'initcreate', encoding: 'json' }; postBackData[Joomla.getOptions('csrf.token')] = 1; Joomla.request({ url: postURL, method: 'POST', data: interpolateParameters(postBackData), onSuccess(response) { try { const publicKey = JSON.parse(response); Joomla.plgSystemWebauthnCreateCredentials(publicKey); } catch (exception) { handleCreationError(Joomla.Text._('PLG_SYSTEM_WEBAUTHN_ERR_XHR_INITCREATE')); } }, onError: xhr => { handleCreationError(`${xhr.status} ${xhr.statusText}`); } }); }; Joomla.plgSystemWebauthnCreateCredentials = publicKey => { const paths = Joomla.getOptions('system.paths'); const postURL = `${paths ? `${paths.base}/index.php` : window.location.pathname}`; const arrayToBase64String = a => btoa(String.fromCharCode(...a)); const base64url2base64 = input => { let output = input.replace(/-/g, '+').replace(/_/g, '/'); const pad = output.length % 4; if (pad) { if (pad === 1) { throw new Error('InvalidLengthError: Input base64url string is the wrong length to determine padding'); } output += new Array(5 - pad).join('='); } return output; }; // Convert the public key information to a format usable by the browser's credentials manager publicKey.challenge = Uint8Array.from(window.atob(base64url2base64(publicKey.challenge)), c => c.charCodeAt(0)); publicKey.user.id = Uint8Array.from(window.atob(publicKey.user.id), c => c.charCodeAt(0)); if (publicKey.excludeCredentials) { publicKey.excludeCredentials = publicKey.excludeCredentials.map(data => { data.id = Uint8Array.from(window.atob(base64url2base64(data.id)), c => c.charCodeAt(0)); return data; }); } // Ask the browser to prompt the user for their authenticator navigator.credentials.create({ publicKey }).then(data => { const publicKeyCredential = { id: data.id, type: data.type, rawId: arrayToBase64String(new Uint8Array(data.rawId)), response: { clientDataJSON: arrayToBase64String(new Uint8Array(data.response.clientDataJSON)), attestationObject: arrayToBase64String(new Uint8Array(data.response.attestationObject)) } }; // Send the response to your server const postBackData = { option: 'com_ajax', group: 'system', plugin: 'webauthn', format: 'raw', akaction: 'create', encoding: 'raw', data: btoa(JSON.stringify(publicKeyCredential)) }; postBackData[Joomla.getOptions('csrf.token')] = 1; Joomla.request({ url: postURL, method: 'POST', data: interpolateParameters(postBackData), onSuccess(responseHTML) { const elements = document.querySelectorAll('#plg_system_webauthn-management-interface'); if (!elements) { return; } const elContainer = elements[0]; elContainer.outerHTML = responseHTML; Joomla.plgSystemWebauthnInitialize(); Joomla.plgSystemWebauthnReactivateTooltips(); }, onError: xhr => { handleCreationError(`${xhr.status} ${xhr.statusText}`); } }); }).catch(error => { // An error occurred: timeout, request to provide the authenticator refused, hardware / // software error... handleCreationError(error); }); }; /** * Edit label button * * @param {Element} that The button being clicked * @param {String} storeID CSS ID for the element storing the configuration in its data * properties */ // eslint-disable-next-line no-unused-vars Joomla.plgSystemWebauthnEditLabel = that => { const paths = Joomla.getOptions('system.paths'); const postURL = `${paths ? `${paths.base}/index.php` : window.location.pathname}`; // Find the UI elements const elTR = that.parentElement.parentElement; const credentialId = elTR.dataset.credential_id; const elTDs = elTR.querySelectorAll('.webauthnManagementCell'); const elLabelTD = elTDs[0]; const elButtonsTD = elTDs[1]; const elButtons = elButtonsTD.querySelectorAll('button'); const elEdit = elButtons[0]; const elDelete = elButtons[1]; // Show the editor const oldLabel = elLabelTD.innerText; const elContainer = document.createElement('div'); elContainer.className = 'webauthnManagementEditorRow d-flex gap-2'; const elInput = document.createElement('input'); elInput.type = 'text'; elInput.name = 'label'; elInput.defaultValue = oldLabel; elInput.className = 'form-control'; const elSave = document.createElement('button'); elSave.className = 'btn btn-success btn-sm'; elSave.innerText = Joomla.Text._('PLG_SYSTEM_WEBAUTHN_MANAGE_BTN_SAVE_LABEL'); elSave.addEventListener('click', () => { const elNewLabel = elInput.value; if (elNewLabel !== '') { const postBackData = { option: 'com_ajax', group: 'system', plugin: 'webauthn', format: 'json', encoding: 'json', akaction: 'savelabel', credential_id: credentialId, new_label: elNewLabel }; postBackData[Joomla.getOptions('csrf.token')] = 1; Joomla.request({ url: postURL, method: 'POST', data: interpolateParameters(postBackData), onSuccess(rawResponse) { let result = false; try { result = JSON.parse(rawResponse); } catch (exception) { result = rawResponse === 'true'; } if (result !== true) { handleCreationError(Joomla.Text._('PLG_SYSTEM_WEBAUTHN_ERR_LABEL_NOT_SAVED')); } }, onError: xhr => { handleCreationError(`${Joomla.Text._('PLG_SYSTEM_WEBAUTHN_ERR_LABEL_NOT_SAVED')} -- ${xhr.status} ${xhr.statusText}`); } }); } elLabelTD.innerText = elNewLabel; elEdit.disabled = false; elDelete.disabled = false; return false; }, false); const elCancel = document.createElement('button'); elCancel.className = 'btn btn-danger btn-sm'; elCancel.innerText = Joomla.Text._('PLG_SYSTEM_WEBAUTHN_MANAGE_BTN_CANCEL_LABEL'); elCancel.addEventListener('click', () => { elLabelTD.innerText = oldLabel; elEdit.disabled = false; elDelete.disabled = false; return false; }, false); elLabelTD.innerHTML = ''; elContainer.appendChild(elInput); elContainer.appendChild(elSave); elContainer.appendChild(elCancel); elLabelTD.appendChild(elContainer); elEdit.disabled = true; elDelete.disabled = true; return false; }; /** * Delete button * * @param {Element} that The button being clicked */ // eslint-disable-next-line no-unused-vars Joomla.plgSystemWebauthnDelete = that => { if (!window.confirm(Joomla.Text._('JGLOBAL_CONFIRM_DELETE'))) { return false; } const paths = Joomla.getOptions('system.paths'); const postURL = `${paths ? `${paths.base}/index.php` : window.location.pathname}`; // Find the UI elements const elTR = that.parentElement.parentElement; const credentialId = elTR.dataset.credential_id; const elTDs = elTR.querySelectorAll('.webauthnManagementCell'); const elButtonsTD = elTDs[1]; const elButtons = elButtonsTD.querySelectorAll('button'); const elEdit = elButtons[0]; const elDelete = elButtons[1]; elEdit.disabled = true; elDelete.disabled = true; // Delete the record const postBackData = { option: 'com_ajax', group: 'system', plugin: 'webauthn', format: 'json', encoding: 'json', akaction: 'delete', credential_id: credentialId }; postBackData[Joomla.getOptions('csrf.token')] = 1; Joomla.request({ url: postURL, method: 'POST', data: interpolateParameters(postBackData), onSuccess(rawResponse) { let result = false; try { result = JSON.parse(rawResponse); } catch (e) { result = rawResponse === 'true'; } if (result !== true) { handleCreationError(Joomla.Text._('PLG_SYSTEM_WEBAUTHN_ERR_NOT_DELETED')); return; } elTR.parentElement.removeChild(elTR); }, onError: xhr => { elEdit.disabled = false; elDelete.disabled = false; handleCreationError(`${Joomla.Text._('PLG_SYSTEM_WEBAUTHN_ERR_NOT_DELETED')} -- ${xhr.status} ${xhr.statusText}`); } }); return false; }; Joomla.plgSystemWebauthnReactivateTooltips = () => { const tooltips = Joomla.getOptions('bootstrap.tooltip'); if (typeof tooltips === 'object' && tooltips !== null) { Object.keys(tooltips).forEach(tooltip => { const opt = tooltips[tooltip]; const options = { animation: opt.animation ? opt.animation : true, container: opt.container ? opt.container : false, delay: opt.delay ? opt.delay : 0, html: opt.html ? opt.html : false, selector: opt.selector ? opt.selector : false, trigger: opt.trigger ? opt.trigger : 'hover focus', fallbackPlacement: opt.fallbackPlacement ? opt.fallbackPlacement : null, boundary: opt.boundary ? opt.boundary : 'clippingParents', title: opt.title ? opt.title : '', customClass: opt.customClass ? opt.customClass : '', sanitize: opt.sanitize ? opt.sanitize : true, sanitizeFn: opt.sanitizeFn ? opt.sanitizeFn : null, popperConfig: opt.popperConfig ? opt.popperConfig : null }; if (opt.placement) { options.placement = opt.placement; } if (opt.template) { options.template = opt.template; } if (opt.allowList) { options.allowList = opt.allowList; } const elements = Array.from(document.querySelectorAll(tooltip)); if (elements.length) { elements.map(el => new window.bootstrap.Tooltip(el, options)); } }); } }; /** * Add New Authenticator button click handler * * @param {MouseEvent} event The mouse click event * * @returns {boolean} Returns false to prevent the default browser button behavior */ Joomla.plgSystemWebauthnAddOnClick = event => { event.preventDefault(); Joomla.plgSystemWebauthnInitCreateCredentials(); return false; }; /** * Edit Name button click handler * * @param {MouseEvent} event The mouse click event * * @returns {boolean} Returns false to prevent the default browser button behavior */ Joomla.plgSystemWebauthnEditOnClick = event => { event.preventDefault(); Joomla.plgSystemWebauthnEditLabel(event.currentTarget); return false; }; /** * Remove button click handler * * @param {MouseEvent} event The mouse click event * * @returns {boolean} Returns false to prevent the default browser button behavior */ Joomla.plgSystemWebauthnDeleteOnClick = event => { event.preventDefault(); Joomla.plgSystemWebauthnDelete(event.currentTarget); return false; }; /** * Initialization on page load. */ Joomla.plgSystemWebauthnInitialize = () => { const addButton = document.getElementById('plg_system_webauthn-manage-add'); if (addButton) { addButton.addEventListener('click', Joomla.plgSystemWebauthnAddOnClick); } const editLabelButtons = [].slice.call(document.querySelectorAll('.plg_system_webauthn-manage-edit')); if (editLabelButtons.length) { editLabelButtons.forEach(button => { button.addEventListener('click', Joomla.plgSystemWebauthnEditOnClick); }); } const deleteButtons = [].slice.call(document.querySelectorAll('.plg_system_webauthn-manage-delete')); if (deleteButtons.length) { deleteButtons.forEach(button => { button.addEventListener('click', Joomla.plgSystemWebauthnDeleteOnClick); }); } }; // Initialization. Runs on DOM content loaded since this script is always loaded deferred. Joomla.plgSystemWebauthnInitialize(); })(Joomla, document); js/management-es5.min.js 0000644 00000015635 15172624222 0011123 0 ustar 00 (function(){"use strict";/** * @package Joomla.Plugin * @subpackage System.webauthn * * @copyright (C) 2020 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */window.Joomla=window.Joomla||{},function(t,f){var S=function n(i,e){e===void 0&&(e="");var a="";return Object.keys(i).forEach(function(s){if(typeof i[s]!="object"){a.length>0&&(a+="&"),e===""?a+=encodeURIComponent(s)+"="+encodeURIComponent(i[s]):a+=encodeURIComponent(e)+"["+encodeURIComponent(s)+"]="+encodeURIComponent(i[s]);return}a+=""+n(i[s],s)}),a},E=function(i){t.renderMessages({error:[i]})};t.plgSystemWebauthnInitCreateCredentials=function(){if(!("credentials"in navigator)){t.renderMessages({error:[t.Text._("PLG_SYSTEM_WEBAUTHN_ERR_NO_BROWSER_SUPPORT")]});return}var n=t.getOptions("system.paths"),i=""+(n?n.base+"/index.php":window.location.pathname),e={option:"com_ajax",group:"system",plugin:"webauthn",format:"json",akaction:"initcreate",encoding:"json"};e[t.getOptions("csrf.token")]=1,t.request({url:i,method:"POST",data:S(e),onSuccess:function(s){try{var r=JSON.parse(s);t.plgSystemWebauthnCreateCredentials(r)}catch{E(t.Text._("PLG_SYSTEM_WEBAUTHN_ERR_XHR_INITCREATE"))}},onError:function(s){E(s.status+" "+s.statusText)}})},t.plgSystemWebauthnCreateCredentials=function(n){var i=t.getOptions("system.paths"),e=""+(i?i.base+"/index.php":window.location.pathname),a=function(l){return btoa(String.fromCharCode.apply(String,l))},s=function(l){var o=l.replace(/-/g,"+").replace(/_/g,"/"),c=o.length%4;if(c){if(c===1)throw new Error("InvalidLengthError: Input base64url string is the wrong length to determine padding");o+=new Array(5-c).join("=")}return o};n.challenge=Uint8Array.from(window.atob(s(n.challenge)),function(r){return r.charCodeAt(0)}),n.user.id=Uint8Array.from(window.atob(n.user.id),function(r){return r.charCodeAt(0)}),n.excludeCredentials&&(n.excludeCredentials=n.excludeCredentials.map(function(r){return r.id=Uint8Array.from(window.atob(s(r.id)),function(l){return l.charCodeAt(0)}),r})),navigator.credentials.create({publicKey:n}).then(function(r){var l={id:r.id,type:r.type,rawId:a(new Uint8Array(r.rawId)),response:{clientDataJSON:a(new Uint8Array(r.response.clientDataJSON)),attestationObject:a(new Uint8Array(r.response.attestationObject))}},o={option:"com_ajax",group:"system",plugin:"webauthn",format:"raw",akaction:"create",encoding:"raw",data:btoa(JSON.stringify(l))};o[t.getOptions("csrf.token")]=1,t.request({url:e,method:"POST",data:S(o),onSuccess:function(u){var g=f.querySelectorAll("#plg_system_webauthn-management-interface");if(g){var h=g[0];h.outerHTML=u,t.plgSystemWebauthnInitialize(),t.plgSystemWebauthnReactivateTooltips()}},onError:function(u){E(u.status+" "+u.statusText)}})}).catch(function(r){E(r)})},t.plgSystemWebauthnEditLabel=function(n){var i=t.getOptions("system.paths"),e=""+(i?i.base+"/index.php":window.location.pathname),a=n.parentElement.parentElement,s=a.dataset.credential_id,r=a.querySelectorAll(".webauthnManagementCell"),l=r[0],o=r[1],c=o.querySelectorAll("button"),u=c[0],g=c[1],h=l.innerText,d=f.createElement("div");d.className="webauthnManagementEditorRow d-flex gap-2";var p=f.createElement("input");p.type="text",p.name="label",p.defaultValue=h,p.className="form-control";var b=f.createElement("button");b.className="btn btn-success btn-sm",b.innerText=t.Text._("PLG_SYSTEM_WEBAUTHN_MANAGE_BTN_SAVE_LABEL"),b.addEventListener("click",function(){var T=p.value;if(T!==""){var y={option:"com_ajax",group:"system",plugin:"webauthn",format:"json",encoding:"json",akaction:"savelabel",credential_id:s,new_label:T};y[t.getOptions("csrf.token")]=1,t.request({url:e,method:"POST",data:S(y),onSuccess:function(_){var m=!1;try{m=JSON.parse(_)}catch{m=_==="true"}m!==!0&&E(t.Text._("PLG_SYSTEM_WEBAUTHN_ERR_LABEL_NOT_SAVED"))},onError:function(_){E(t.Text._("PLG_SYSTEM_WEBAUTHN_ERR_LABEL_NOT_SAVED")+" -- "+_.status+" "+_.statusText)}})}return l.innerText=T,u.disabled=!1,g.disabled=!1,!1},!1);var v=f.createElement("button");return v.className="btn btn-danger btn-sm",v.innerText=t.Text._("PLG_SYSTEM_WEBAUTHN_MANAGE_BTN_CANCEL_LABEL"),v.addEventListener("click",function(){return l.innerText=h,u.disabled=!1,g.disabled=!1,!1},!1),l.innerHTML="",d.appendChild(p),d.appendChild(b),d.appendChild(v),l.appendChild(d),u.disabled=!0,g.disabled=!0,!1},t.plgSystemWebauthnDelete=function(n){if(!window.confirm(t.Text._("JGLOBAL_CONFIRM_DELETE")))return!1;var i=t.getOptions("system.paths"),e=""+(i?i.base+"/index.php":window.location.pathname),a=n.parentElement.parentElement,s=a.dataset.credential_id,r=a.querySelectorAll(".webauthnManagementCell"),l=r[1],o=l.querySelectorAll("button"),c=o[0],u=o[1];c.disabled=!0,u.disabled=!0;var g={option:"com_ajax",group:"system",plugin:"webauthn",format:"json",encoding:"json",akaction:"delete",credential_id:s};return g[t.getOptions("csrf.token")]=1,t.request({url:e,method:"POST",data:S(g),onSuccess:function(d){var p=!1;try{p=JSON.parse(d)}catch{p=d==="true"}if(p!==!0){E(t.Text._("PLG_SYSTEM_WEBAUTHN_ERR_NOT_DELETED"));return}a.parentElement.removeChild(a)},onError:function(d){c.disabled=!1,u.disabled=!1,E(t.Text._("PLG_SYSTEM_WEBAUTHN_ERR_NOT_DELETED")+" -- "+d.status+" "+d.statusText)}}),!1},t.plgSystemWebauthnReactivateTooltips=function(){var n=t.getOptions("bootstrap.tooltip");typeof n=="object"&&n!==null&&Object.keys(n).forEach(function(i){var e=n[i],a={animation:e.animation?e.animation:!0,container:e.container?e.container:!1,delay:e.delay?e.delay:0,html:e.html?e.html:!1,selector:e.selector?e.selector:!1,trigger:e.trigger?e.trigger:"hover focus",fallbackPlacement:e.fallbackPlacement?e.fallbackPlacement:null,boundary:e.boundary?e.boundary:"clippingParents",title:e.title?e.title:"",customClass:e.customClass?e.customClass:"",sanitize:e.sanitize?e.sanitize:!0,sanitizeFn:e.sanitizeFn?e.sanitizeFn:null,popperConfig:e.popperConfig?e.popperConfig:null};e.placement&&(a.placement=e.placement),e.template&&(a.template=e.template),e.allowList&&(a.allowList=e.allowList);var s=Array.from(f.querySelectorAll(i));s.length&&s.map(function(r){return new window.bootstrap.Tooltip(r,a)})})},t.plgSystemWebauthnAddOnClick=function(n){return n.preventDefault(),t.plgSystemWebauthnInitCreateCredentials(),!1},t.plgSystemWebauthnEditOnClick=function(n){return n.preventDefault(),t.plgSystemWebauthnEditLabel(n.currentTarget),!1},t.plgSystemWebauthnDeleteOnClick=function(n){return n.preventDefault(),t.plgSystemWebauthnDelete(n.currentTarget),!1},t.plgSystemWebauthnInitialize=function(){var n=f.getElementById("plg_system_webauthn-manage-add");n&&n.addEventListener("click",t.plgSystemWebauthnAddOnClick);var i=[].slice.call(f.querySelectorAll(".plg_system_webauthn-manage-edit"));i.length&&i.forEach(function(a){a.addEventListener("click",t.plgSystemWebauthnEditOnClick)});var e=[].slice.call(f.querySelectorAll(".plg_system_webauthn-manage-delete"));e.length&&e.forEach(function(a){a.addEventListener("click",t.plgSystemWebauthnDeleteOnClick)})},t.plgSystemWebauthnInitialize()}(Joomla,document)})(); js/login-es5.js 0000644 00000021776 15172624222 0007340 0 ustar 00 (function () { 'use strict'; /** * @package Joomla.Plugin * @subpackage System.webauthn * * @copyright (C) 2020 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ window.Joomla = window.Joomla || {}; (function (Joomla, document) { /** * Converts a simple object containing query string parameters to a single, escaped query string. * This method is a necessary evil since Joomla.request can only accept data as a string. * * @param object {object} A plain object containing the query parameters to pass * @param prefix {string} Prefix for array-type parameters * * @returns {string} */ var interpolateParameters = function interpolateParameters(object, prefix) { if (prefix === void 0) { prefix = ''; } var encodedString = ''; Object.keys(object).forEach(function (prop) { if (typeof object[prop] !== 'object') { if (encodedString.length > 0) { encodedString += '&'; } if (prefix === '') { encodedString += encodeURIComponent(prop) + "=" + encodeURIComponent(object[prop]); } else { encodedString += encodeURIComponent(prefix) + "[" + encodeURIComponent(prop) + "]=" + encodeURIComponent(object[prop]); } return; } // Objects need special handling encodedString += "" + interpolateParameters(object[prop], prop); }); return encodedString; }; /** * Finds the first field matching a selector inside a form * * @param {HTMLFormElement} form The FORM element * @param {String} fieldSelector The CSS selector to locate the field * * @returns {Element|null} NULL when no element is found */ var findField = function findField(form, fieldSelector) { var elInputs = form.querySelectorAll(fieldSelector); if (!elInputs.length) { return null; } return elInputs[0]; }; /** * Find a form field described by the CSS selector fieldSelector. * The field must be inside a <form> element which is either the * outerElement itself or enclosed by outerElement. * * @param {Element} outerElement The element which is either our form or contains our form. * @param {String} fieldSelector The CSS selector to locate the field * * @returns {null|Element} NULL when no element is found */ var lookForField = function lookForField(outerElement, fieldSelector) { var elInput = null; if (!outerElement) { return elInput; } var elElement = outerElement.parentElement; if (elElement.nodeName === 'FORM') { elInput = findField(elElement, fieldSelector); return elInput; } var elForms = elElement.querySelectorAll('form'); if (elForms.length) { for (var i = 0; i < elForms.length; i += 1) { elInput = findField(elForms[i], fieldSelector); if (elInput !== null) { return elInput; } } } return null; }; /** * A simple error handler. * * @param {String} message */ var handleLoginError = function handleLoginError(message) { Joomla.renderMessages({ error: [message] }); }; /** * Handles the browser response for the user interaction with the authenticator. Redirects to an * internal page which handles the login server-side. * * @param { Object} publicKey Public key request options, returned from the server */ var handleLoginChallenge = function handleLoginChallenge(publicKey) { var arrayToBase64String = function arrayToBase64String(a) { return btoa(String.fromCharCode.apply(String, a)); }; var base64url2base64 = function base64url2base64(input) { var output = input.replace(/-/g, '+').replace(/_/g, '/'); var pad = output.length % 4; if (pad) { if (pad === 1) { throw new Error('InvalidLengthError: Input base64url string is the wrong length to determine padding'); } output += new Array(5 - pad).join('='); } return output; }; if (!publicKey.challenge) { handleLoginError(Joomla.Text._('PLG_SYSTEM_WEBAUTHN_ERR_INVALID_USERNAME')); return; } publicKey.challenge = Uint8Array.from(window.atob(base64url2base64(publicKey.challenge)), function (c) { return c.charCodeAt(0); }); if (publicKey.allowCredentials) { publicKey.allowCredentials = publicKey.allowCredentials.map(function (data) { data.id = Uint8Array.from(window.atob(base64url2base64(data.id)), function (c) { return c.charCodeAt(0); }); return data; }); } navigator.credentials.get({ publicKey: publicKey }).then(function (data) { var publicKeyCredential = { id: data.id, type: data.type, rawId: arrayToBase64String(new Uint8Array(data.rawId)), response: { authenticatorData: arrayToBase64String(new Uint8Array(data.response.authenticatorData)), clientDataJSON: arrayToBase64String(new Uint8Array(data.response.clientDataJSON)), signature: arrayToBase64String(new Uint8Array(data.response.signature)), userHandle: data.response.userHandle ? arrayToBase64String(new Uint8Array(data.response.userHandle)) : null } }; // Send the response to your server var paths = Joomla.getOptions('system.paths'); window.location = (paths ? paths.base + "/index.php" : window.location.pathname) + "?" + Joomla.getOptions('csrf.token') + "=1&option=com_ajax&group=system&plugin=webauthn&" + ("format=raw&akaction=login&encoding=redirect&data=" + btoa(JSON.stringify(publicKeyCredential))); }).catch(function (error) { // Example: timeout, interaction refused... handleLoginError(error); }); }; /** * Initialize the passwordless login, going through the server to get the registered certificates * for the user. * * @param {string} formId The login form's or login module's HTML ID * * @returns {boolean} Always FALSE to prevent BUTTON elements from reloading the page. */ // eslint-disable-next-line no-unused-vars Joomla.plgSystemWebauthnLogin = function (formId) { // Get the username var elFormContainer = document.getElementById(formId); var elUsername = lookForField(elFormContainer, 'input[name=username]'); var elReturn = lookForField(elFormContainer, 'input[name=return]'); if (elUsername === null) { Joomla.renderMessages({ error: [Joomla.Text._('PLG_SYSTEM_WEBAUTHN_ERR_CANNOT_FIND_USERNAME')] }); return false; } var username = elUsername.value; var returnUrl = elReturn ? elReturn.value : null; // No username? We cannot proceed. We need a username to find the acceptable public keys :( if (username === '') { Joomla.renderMessages({ error: [Joomla.Text._('PLG_SYSTEM_WEBAUTHN_ERR_EMPTY_USERNAME')] }); return false; } // Get the Public Key Credential Request Options (challenge and acceptable public keys) var postBackData = { option: 'com_ajax', group: 'system', plugin: 'webauthn', format: 'raw', akaction: 'challenge', encoding: 'raw', username: username, returnUrl: returnUrl }; postBackData[Joomla.getOptions('csrf.token')] = 1; var paths = Joomla.getOptions('system.paths'); Joomla.request({ url: (paths ? paths.base + "/index.php" : window.location.pathname) + "?" + Joomla.getOptions('csrf.token') + "=1", method: 'POST', data: interpolateParameters(postBackData), onSuccess: function onSuccess(rawResponse) { var jsonData = {}; try { jsonData = JSON.parse(rawResponse); } catch (e) { /** * In case of JSON decoding failure fall through; the error will be handled in the login * challenge handler called below. */ } handleLoginChallenge(jsonData); }, onError: function onError(xhr) { handleLoginError(xhr.status + " " + xhr.statusText); } }); return false; }; // Initialization. Runs on DOM content loaded since this script is always loaded deferred. var loginButtons = [].slice.call(document.querySelectorAll('.plg_system_webauthn_login_button')); if (loginButtons.length) { loginButtons.forEach(function (button) { button.addEventListener('click', function (_ref) { var currentTarget = _ref.currentTarget; Joomla.plgSystemWebauthnLogin(currentTarget.getAttribute('data-webauthn-form')); }); }); } })(Joomla, document); })(); js/login.min.js.gz 0000644 00000002740 15172624222 0010035 0 ustar 00 � �V_S7ϧP4�#E�L��+(%n�����1���p����s��ޑ�g �~���j��ow�ի��������Gc����E�+o]5�2���Ò�`&+���%5�ڪ|�B䘢��o��Y �MeS@��{����N9�y�}钽��j�?� ����B��]k��z�,�y5+T�N6�w`�2�EƢBz�}� ���x0���_�W{+�3��W�ѿ��F�c)uj��D3+0�<��_Y��f� ��֎h���d� j5'~]��#} ���ȋi�y:����^��]�{�2+�����tj2���ei4hO�6�A:mn�'_Z�\?%r�̍�M+��d��i(� �cd�#��W`�c( �����U��ޟ$�*��e[md���䥦ݫ~+�楴����%hk��H.!Dﷳ�S�}'r�R� 0��ύ]bd��y��K�9R����/w��*rb��$ )��[���кW-j�-��)8'sp�k�M���� [F��H+@̼�d��9�[�<^H{l2 �s����|�P2��z/gx�{�4P�0�D@�Η�K�T !�P��f�4�� �F�P��Be'�?�4�e��L:����E�r�/ ���9j oP�Ri@��2�sL�fWG��5�ᵤ��Q�`�i9Ӵ�Ӆ,�4�uA��ϞO >?y?�5��N��ztu�a4\\L��?�N��W����t�iWy�Y�Ji�S�cK6�/��Oj��B���'��2�eQ�ձ��W�p���(�&�,2�*�;�̈�@��N���� r�.#(��D7���G]�*K�t�)~���a�Xrso/(e\i��� �A�;��7�m�Wܔ��P�}��q|6z��cVJ�S������-��r`?H���-�=��9A�l����0)b��J��v�v���/��M���S�/���S:�ϼ\�7��Q��Khw��:Rg�ܛ[И6�M�����T~��{�5U)ZKze�ӢȽ q�+W=y+��0�ҽ��J��B�,���I/�N(���-��kbh~�J��pE� ��;^y���Qz�?µ48���_�Ì� d�� +�s���۶�'-^{�z�D�������r��p�>& e/�l���w���I�О�n\�8��K��=eC)�6� �2�YL}��B���'��>fm�l� �� ��9̺2��t9Hk��E"�~y�tQNDg��x��+p�ԕ-���z�d�?6� [�_�,��g�K�Bi'))3z\�)8G�ct.����X���M���Y�9m���T��ovjŝ��r �?�77��yk61Y�� wa��, �~c =4m�5�7�m:�U���b3�{��v�M��̲�h���1�i��[�H�V6�M�����и�|�e� !=�ުY���ם=��m)4=m(iwf��� ]M�/� �Ɖ> js/management.min.js.gz 0000644 00000004544 15172624222 0011045 0 ustar 00 � �Y{s۸��>��"�a;s�t�ª��r��5�r�#C�JB<