From 20a018db2e4add32c400cfced3ec6d23e98f95e5 Mon Sep 17 00:00:00 2001 From: Jakob Borg Date: Wed, 4 Jun 2014 22:00:55 +0200 Subject: [PATCH] Implement API keys --- auto/gui.files.go | 4 ++-- cmd/syncthing/gui.go | 8 ++++++++ cmd/syncthing/gui_csrf.go | 3 +++ config/config.go | 1 + gui/app.js | 17 +++++++++++++++++ gui/index.html | 5 +++++ 6 files changed, 36 insertions(+), 2 deletions(-) diff --git a/auto/gui.files.go b/auto/gui.files.go index 1c46967f..f3c39735 100644 --- a/auto/gui.files.go +++ b/auto/gui.files.go @@ -18,7 +18,7 @@ func init() { bs, _ = ioutil.ReadAll(gr) Assets["angular.min.js"] = bs - bs, _ = hex.DecodeString("1f8b080000096e8800ffec3cfd73db36b2bffbaf40f5d223d5c894937777ef4d5ce72675d23b5fbe3c71d279f35cbf194a8424d614a910a06d8dabfffded0220852f52b49db4bd99f34c1b1b58ec17168bdd05c0f1981c17ab7599ce179c84c743f2f4e0c99fc93fe3cb62427e28ca3989f384147c414b322d725ea6938a17258bc88b2c236214232565b4bca249b407d83e314a8a19e18b94115654e594c2c08412f8735e5cd132a70999ac012d797bf2719ff1754649964e690ee3f822e6640a5d138aa8664505c4d31cda29797372fceaddd92b324b331aeded8dbffb856569cec9a42cae81fc33c2cb8a8e0493695ed1faef555631fc4ffe4dbe1bc3c879564ce28c3c7a466671c60028cee7551697ea6f04da0b2af88581bc531e1ceeed5dc52561eb7c0a62e57372548f8896455265340c9abe6044ce2f8687624055669318d01c91005424f0347011303a4be7e1ac8286b4c849f868c1f9eab42caed284964372bb47e0c7688c123a8bab8cb3e88695b37fd018dadec54b41e07ff68fcf3efcb8ffb1b8a43910da31f6b8282e535a8f35466e86369bbc2cb28c96617056b71ef332034135ded9b458812205c99a7754c1aaa4572f638e640e0e9bd639e5ef5f43134ec9b6157514975c2a58cc0470220411d891959c0a820c006e37875627a8d36d5fae4f5ea28c81d19a83452292f30b0f92931c0535d853fdabb2e0c5b4c88e1730ff60c70d9b1a0c2d4b581f2e6e4669fe0afb5c6ec08868e6b25ed255514b2ada61499c8145e673060b645694944c8a22632483d98416ce696952e45c00032fa2fd364d9e91e04dca38cd0111cc2068610a662f66969c2ae98884202f9204a6845106807cbd822515707ac3e12f3553724d6d461af2b7f1cd19cd93d79315d3d0bfaff8bcc079fd80a6f0265da6e06b5ea73f8cd9708b3baf96135a7662ff00f8e2fc240741afe2ec4ca3207b48dd45c23b6356d6e547ae3aef8fff342e635844d907fab902205d39a032020a8291792274b405e98f1f9048a3b4348fc87f048f4964af9c80feaad728fc5d38cd1779fe2a8f27194d3422b28bbc4cc1eec0c3afb788d13e3bf97e534c5b908a9e07e13c2d4ade8e90a8eefe3a3ec3f61fe476a3af1d6c26db769d4d63fca7d3fcd49553b610ecf40fbe30bde0bc4acffc0b5bad577d623e9d3c64317f3205456c2f2ad88b61879dc6c2f17f3244de89f03466ecba28936ea41a9442bcdab67472fbf18dbe6c3112f9c7c78fa7671048940408f5b2a15addcde6069bd559359d529ad024acf736fc496724fc466c657aab3655699ef27078687685c17fe49483349762370886e8fee32c0c16b04d0716b4bb51e2cfc66061bb6dde918dedc06e2610962d2a9e14d77937a46f073799deb8cafd3106ffe46ab65dac92f2aaccdbd4e19f9036addf4ee2e96552162b300aa0073608667149d793222e13150f6e5a26a54bc0660b9f811c0b046e62259d37112f458030ac63c5c72418b3352cd925f0c8d0ee18d382c424e6b12d9c69a0873e139018810d1cafb13c94e14ae8e74e21af27481fb7fdfdfde417d81923d0190bf5c06518c1aa7b154f171af2347126c6ab001110fd0dd11c05d04073cc203e7d38392e96ab2207578198faaa475383c07b9e26178e266ca9f4dffd3c6ad168ef99c228372fae813ac6c410855e87c39101c131a80c1166bf899d87644c9e1c1c1c989069a21c55fda385da30de140d1d20e80c73a93615096f869dd12266efaf73880657b4e46ba16a0f3cfed4c9d6a1d3bb715a386cb97e2c481427051c15042fc0fedb982fa2657c131e8cc87f93efa42e05c449fec39a53f6b1e0b095ef7b1203070a95c793a1cba141b9a8f82ed210a2f5a16d80b512df4096cba70b12d236d53a4a39e82b8207d09c8d8dcf4398c995ed26762d0699f4f45e0776aae427b739dcb3d32188b578c50c778acdf6de81bb7c3133573dc2c1ba3f82ecabca21194e7308c3fc5b0b840ef9658ebb9deedd0d0a2e6a9828480c608d7d83245a319ff162b502ca5ecca2cac0e51a0ed0f379c888feede81a5cfc7b7e7011f1e21310288f616ac0993f961d302f13c6cbf0c9f0d094430d3f22034c0161b31d905f7f25dbd69324a3035b16d9fd18ba4938d872894583535a4ec13fc773aa26e631197c3b1c78a5552ad104f2ccf87106b1dfd79ff0349f155f61b6134cbaca2f36d9c68c0529cc4d2b65b51083b630698b86c9896fc5b42ad3650c09980f93477dd61c9a46f1d52712f6c936893dea958540e1af05fe837e588d295c4d39480510b05b78ed0417962431f601683c1cda7a15bbd12c2b204203327eb788a52c8f5bc4e6e399113b23b7e8e601ceb379a901d13bf8f7e4e58569740868eba66e8f302acba8208b4a0455f836b5c6b5ae082f44fc1358e117a1587c6d1fa93c140971b1d8946117fa766863ecf03a81280408f11b6fecd1ecc914a5fa57d06b7179577daae4e42e4a5b42b4c7dab5e53aeb3facba5cffd84b67ae33dca9b376df88b2625de637d698624c284d9585ba7cfbdf3ae65b53f9ef2682e5043af7a976517ea23ba7019931391586a61d34b4b0a920ae68c900b78fbfafa99e2c85bdf7a776da3be619b6db04093bda31c545099698d3887315fd980530649cea3506e4b7269b6f554924d64323df401115de28a3f99c2f20e4224f5a246ee2830e41153688955b8d411d8cedb40615ada8de9e21ca60d016a134f30ce45b06eb201d329a165347ff90d3fed51f44e069ed3b9fe0f614e7d212ac61a135619a5efa2a25ac64ca25060d3b55b44b3f7d94d35b333449b9566ff76b663c8650ed929298608511631418bb6eba8dd3c54881bc5fd5c9767d968c6342135601e9f9b70f1716d13bf100808e030bba4aa6be95505121f7ab88c557b4b78a5855c2ff8a259527e95379926a3ac2e674f59b4626fab98a33e6d7cea853c14348689ded5cfeec400f4a6b416daa339d858ae5a169932033a314edb63e3826d76996919c827410044f68232ba84b15bcade0c6e52992071d22f36ce34ec10c5b2ba1ee49b679c420178e2dcd8bd52a5b03fbd7a4395bcef0542d5bef796898b3d46da0d69c798bd85b15f4c22527a91d5173cc6fd5f15b2588e4519a0a9988ad7d13ea8c97115b65290f8311aeb178a56d8037da067813718829c18312fb9c4196da5605730acf400e16e73fcfdebf8b98b81090ce2c250c47e476212e88b067e436382e72e089ef7f04c71cc0028f6122d571dbf81756e4c1c6287eef75bb8a019efd0cdaaa74c28a5bfd80714464da5ccb99d45d8f685ad4a630076dbed4baf5a13baeb3eb148bb5d774b2c21a46b3986161e7e2d4457705fe0536740f021a34b03f22cb8165ac1d6bdf5dd7363227b13171c3947e4c97b4a8786395a1c7595c43ec575c47b8c61124d2a8d4bf5a6446e2a4a265dd755e9f915c8aff5bdb8b3a7abc9749f96d413bcd740bd6beb343e7f8f3ae46b9e969761ef93102f106e056405aa3adca1296ba1af128a237b0f293f016a6a61ee4b08224407daf6ec07579d568809dd16c264fa9ac5cc848855c79b78c45cd6d047093e4a809579be6e89722cdc17312cf7245e057c04951468fc08e4f4bc1b41183e294d56afb02014eea264086e2815a9a7cd68ef2d9a2b80efcb8e2640732df2cdeeafa02f693751e2f81ff4d8f99b49698772afd30bfbda2130a893cdda96c87a27319411c66fa55b2fb36814f0ffd925a6f4652af0f3d5ed39682ecede12904a4cd87e668c5192f6e2cf29cd7388bf79fbf893e717868a1b63a7a08fb00816da1dd09e88ed77e9730c99302759a6d9d3b83971b91a4c8e988a4877715b497e937c5088fee1da8c677db1503b0802c9ed2704cc6c07000e49a96fdbac53869aca3588742e3ba7c7efe9e5172430435e92a4ade761047e12425df9b0b571691a0e3f1635f2959873d4f2ff4429fa9a28e6b26f5e0adc4870ea8e2dccdbaf06752d2f8b2478959ded9004c2d0b5c4abcaad82274f7fe164717b1a2e4615ddd8d4b7a5f7ff4475897e2e142cd675bf4a8d7685b9d7b6fdf8ec18febcd5bea6d9dfe228588cdf6eff7b0eadc9a2230cc43c7ecf39e156d5df87603f5481c6759f73cd41e52b3a8edecd98e4519b55386d4c0b4621ff3c7d578fb0493f59ea6216fabb8b6d1568aa411a658e4b9f30060a7754c331a97afeacb319d71a2feaac0e0f3dce45a95cef7c9930bc1d6ceed538c1b0b4e5a22d95999426291addd698545adb3ba0d4cee6ebca21ea8ef667e1366228d80ff37dbd4b471d423bbb28f7dc361478118f0b4d43656451f83a9e1ccfb90adc9dd07e8be5b72a7461835b0d6e44e1b03e6928903ef7ace6edd0c420757d19f738fd309ff76913aaffdcb857b99d90adb3da8d4e115e6337ffa938fd61620c22d4238b1014bf15cd0b9bce4635540e233098d926f6f6e1dfb9ad2158c78dccd1b3e0259b2e812807dd6b70b7b77ffafbf92bfdc37b14703ed99e921d92f90e9411aec98fd4e7bbf356c0a0283cdfd13e0df5e64cc113a65966fe056c597c8110c9e9d1c4151f1da9403d5c479e7176e9fb9cab5c0c15de8cd36208f793147f562f145e57e7279ed528e242d7fb0a20921a3865be98a9e2946ecb2bb1dc8e08f2c4cf8f9b56e5436301ea7e2460a12d6703bae0c411df74a9cc1c88590ae0560dcd1a21f7d0e62c0ab532687e83c5c84d68d615343b6363c92f618f0da7483be9b37d6381f7a378b91c58b7a8cb444f5575b268376cfd017a4c2d0dbf6ef3f546ac316909b31cba1d4d6e704d610f6b42de1d64d1e0fe2ed5c02f118b177135459d74542ed947d386ca9844b7422e1f444eea25314820723d272dc242da47b2be9e512bf4cc55019ac61899e6ddbb8c4f34053fc572991e12b34dd52773f8352f7a5eefaaa400df33e2bd841f18e0fafea95e87f5ca541a847e8e2758d5b1fd8c1949aa53b32d5bc876f65aaedd87ac7c1b6aadd192734adb52707d7bb6d3aee83f7159f7cc0f5d378fcf76dbc0adbd7502b0271f7d57ed4d66b2ac678a7fd7ef3d12c50610a7adbcea280fe8a1302d6fa257a680a24cf5ff1005688d3b0a6a9348c47645273a9ddd68ac5bd29f9a0617b5f0b332e0530f102d877e2149aef15f8d0571ad97fe2787b35ecb91aa654b0a7619551a3c0eb14602dbc72dc16b31cfabc190adad1742336c216ddc4d1cbb48458af28d78274f3577fea5b04cf75042e0f68c899fef18ca596a1679e1ddaa8b22ccfcb3ad8516c2863a9af3dba04c5c6b2d429665a8c609d272d7562998c0196784634d4a5cee40ad6546a7291995c24749a2ef1e61558f288e495c14c92ce53cef03df7b40eb2714af0f30bce630d85fea0e645fc2311d4affae43b0af16b56cce52ff144901ee243bda6e7c9411daf2065eb5120f048f615665334c9e646ff788aaa1506790c10b1f9c9949a7b355a7b249baf2a3e22e279914744d11df1e2c7f4862661a34063d4d683585f73a9199aa4792cbea9d0971f7b958b46310d8d27687b3f74405a1f21492ccfc1673dfd33f94effc7490205e4f8c8037ae8a3daada5a7437c981690bfa77761ad0f4f0f60e66d3f663ab97800f9d77ef2fa4ba412bfc754db038e0976d9d992e21794fe4076269e6969ff7468d3067d889ddd85b33e2c3dc4cc7af1d2c9c403a85f7e0523630bf92597fbd898c1bcf732780bd138bb8ed7ec5dfdd598af6fdfde778d3afbbb389e2eaafcf2e4e51766d6c7aafec241dc748c4bb10d4b2d8bf717e138ba7d32faeb663cb7737001bc13ad6a12c02a15d90f764e9ab09453b0b2df5d09f2d2c3f8fce7f1cf3f5f8cbd3ac08abe944f1dde7d7f44feb3c5383403f01ac8208aa2313ed59608197e702fd491ef3f1daa52cb78b0538d782a983f6cc1f93ee92140b7f74cbe55f74cdab84944249d5ed1302844862acbf95d7ce96cc86ffb3d23c1b1564f55c4d5c7039b665ec6399b6655e2f488e4cbaebaaa0bd380fb48fdaa91d86868e912c871fc20d1f7d2ac30d33a1ae0779406249fef8b77c24703330f3f57382388bd07cfbf1f8b91cf15854e355579fab912c5324d495d3afa5cc160fc38d6fc2d72a24991a5f9e5b32d0ea18611a1d9724462ce4b88daa7bccc6c6bc5b6e811d81da3258baa9c2dd2997603f92aa5d73fc599bf902f1eadf729cfd53fe331b9a604967c952579c065680cdaf6024bce40b33f2154cad796b6c4f1c2a1335455adb7bcc9925f23c8450773f8514b042714056124ce4a1a27eb7bb127ea7dedfcede621654422fca2da715a948d35fa31c76c9c43f94e7316138a097d9afcdb9e77cf98a9ae6e83f673202e63a0ef1777f71be9bec065415b318a4a1d2bfcdff98bfdff7dbaff5f17b77f79ba79346efd1ed14324df297d2fe46d0b5160ff7a0be4ff010000ffff010000ffff8226dc91c6570000") + bs, _ = hex.DecodeString("1f8b080000096e8800ffec3cfd73dbb692bffbaf4075e923d5c89493bed7bb89ebbc499df43dbf7c79e2a47373ae6f8612218b35052a246845e3e87fbf5d00a4f0458ab693b66fe63cd3c60616fb85c5627701703c26c7f9725da497734ec2e321797cf0e8afe45ff1553e213fe5c525895942723ea70599e68c17e9a4e2795146e459961131aa24052d69714d93680fb07d2829c96784cfd3929479554c290c4c28813f2ff36b5a309a90c91ad092d727eff74bbece28c9d22965308ecf634ea6d035a1886a9657403c65d04ec9ab93e3176fce5e90599ad1686f6ffcdd6f6596324e2645be02f24f082f2a3a124ca6aca2f5dfcbac2af13ff937f96e0c232fb37c1267e4c113328bb312806276596571a1fe46a0bda0825f4a9077ca83c3bdbdebb820e59a4d412c76498eea11d1224faa8c8641d3178cc8f9c5f0500ca88a6c12039a2312808a049e062e024667e96538aba021cd19091fcc395f9e16f9759ad062486ef608fc188d5142677195f132fa5416b37fd218dadec40b41e0bff78fcfdefdbcff3ebfa20c08ed187b9ce75729adc71a2337439b4d5ee459468b3038ab5b8f799181a01aefe5345f822205c99a7754c1b2a0d7cf638e640e0e9bd64bcadfbe84269c926d2bea282eb854b09809e0440822b0232b8c0a822500dc6c0ead4e50a7dbbe589f3c471903a39581452292f30b0f921386821aeca9fe6591f37c9a67c773987fb0e3864d0d861605ac0f177749297b817d2e3760443473592fe832af2515edb024cec022d965090b649617944cf23c2b4906b3092d9cd3c2a4c8b900065e44fb4d9a3c21c1abb4e49401229841d0c214cc5ecc2c3955d21109419e25094c49494b00e4eb252ca980d34f1cfe523325d7d466a4217f1d7f3aa32c793959961afab715bfcc715edfa129bc4a1729f89a97e94fe372b8c5cdaac584169dd8df01be989d3010f43acece340ab287d45d24bc3566655d7ee4aaf3eef84fe322864594bda31f2b00d295032a23a02018c912a1a32d487ffc80441aa5a57944fe33784c227be504f457bd46e11fc2693e63ec058b27194d3422b28b3c4fc1eec0c3afb788d13e3bf97e954f5b908a9e7be13ccd0bde8e90a8eefe3a3ec3f69fe476a3af1d6c26db769d4d63fc875376eaca295b0876fa075f985ef0b24acffc0b5bad577d623e9cdc67317f3005456ccf2ad88b61879dc6c2f17f3044de89f0342ecb555e24dd4835288578b96de9e4f6fd2b7dd96224f2cff7ef4fcf2090280810ba850d3d3b3d7949d71a326820b245a18897e915fc6d4d52b325c21677564da794263409eb1d117fd21909bf111ba0deaa4d70ca521e0e0fcdae30f80f4639e8e04aec21c110378d380b83396cee8105ed6eaff8b33158d86eb6b764633bb09b09842de7154ff215eb86f4edfb26d31b57b93fc7e0d55ccdb68b55505e15ac4d1dfe0969d3facd249e5e2545be043b007a60b96017600d933c2e1215456e5a26a54bc066e39f811c73046e222c9d371165458030ac23cc872418976b58e80be0b144bb2b4b2db44c621edbc299067ae833018911d8c0f11acb4319e4847eee14f27a82f471dbdfdf4e7e83fd34029d95a11eee0c2358ab2fe2e95c439e26cec4781520c2a8bf239aa3001a28c3bce3c3bb93e37cb1cc193818c4d4573d9a1a04def334b97034614ba5ffeee7518b617bcf14c6c62c5f01758ca421765d85c39101c131140d1166bf89b887644c1e1d1c1c989069a21c55fda305e830de140ddd26e80c33b03615096f869dd13c2edfae18c4904b5af0b550b5071e7fea14edd0e9dd382d1c366a3f16248a93028e0a421e60ff75cce7d122fe141e8cc87f91efa42e05c409fb69cd69f93ee71000ec7bd209070a95c793a1cba14139aff82ed210d8f5a16d80b512df406ecca77312d236d53a4a39e82b8207d09c8d8dcf43982999ed26762d06992af55e077682e527b739dcb3932888d078551aee149bedbd0337f67c66ae7a8483757f04395bc520854e19046ffead05020e76c570b7d3bdbb41c1450d1305e904acb16f90442be6339e2f9740d98b59d426b85cc3017a3e0f19d1bf1d5d838b7fcf0f2e229e7f0002c5314c0d38f387b203e66552f2227c343c34e550c38fc8001347d86c07e4f367b26d3d49323ab06591dd0fa19b84832d97586a38a5c514fc737c49d5c43c24836f8703afb44a259a409e193fce2062fcfa139eb259fe15663bc154adf862936dcc5890c2dcb452560b31680b93b6684a39f1ad989645ba88216df361f2a8cf9a43d328befa44c23ed926b147bdb27c28fcb5c07fd00fab3185cb2907a90002760baf9de0c29224c63e008d87435baf62379a6539446840c6ef16b100e6718bd87c3c336267e416dd3cc079362f35207a03ff9e3cbf308d0e016dddd4ed1146651915645189a00adfa6d6b8d625e1b9887f022bfc22144bb6ed23958722212e169b32ec42df0e6d8c1d5e2710e503217ee38d3d9a3d99a254ff0e7acdaf6eab4f959cdc46690b88f6ca766db9cefa4fab2ed73ff6d299eb0c77eaacdd37a2ac58cdf99d35a618134a53c5a42edffef78ef9d654fe8789603981ce7daa5d945fe8ce6940664c4e85a169c7132d6c2a886b5a9480dbc7dfd7544f96c2defb4b3bed1df30cdb6d82841ded98e2a2040bcc69c4698c7e380318324ef51a03f25b93655b551289f5d0c83750448537ca28bbe47308b9c8a316899bf8a04350850d62e5566350c7693bad41452baab767883218b44528cd3c03f996c13a48878ca6c5d4d13fe4b43ff883083ce37de313dc9e62262dc11a165a13a6e9a5af52c24aa65c62d0b05345bbf4d34739bd354393946b557abf66c66308d5ae2889095618314681b1eba6db38938c14c8db659d6cd727d03826346115909e7ffb7061e9bd130f00e838b0a0ab64ea5b09157575bf8acaf89af656515915f0bf7c41e5f9fb549ebf9a8eb03993fda691897eace2acf46b67d4a9e02124b4ce762e7f76a007a5b5a036d599ce42c5f2d0b44990b9a414edb63e6e26ab34cb08a3201d04c113dac80aea52056f2bb871798ae4f188c83cdbb85330c3d64aa87bfe6d1e31c885634bf36cb9ccd6c0fe8a3427d2199ec565eb3d0f0d7396ba0dd49a336f117bab825eb8e424b5236a2e075875fc5609227900a74226626bdf843ae345542eb39487c108d758bcd436c04fda06f829e21053820725f639832cb52df3d2293c0339589cff3a7bfb262ac53582746629613822377371ada47c426e82e39c014f7cff3d38e6401c79016bf2906efc5b99b3606314bff7ba5dc500cf7e066d553a61c5ad7ec03822326daee54ceab647342d6a539883365f6add15d11dd7d92ac562ed8a4e9658c36816332c6c264e5d7457e05f6043f720a04103fb23b21c58c6dab1f6dd756d2373121b13374ce9fb7441f38a3756197a9cc50a62bf7c15e11a479048a352ff6a911989938a9675d779e9467229fe6f6d2feae8f14e26e5b705ed34d32d58fbce0e9de3cfdb1ae5a6a7d979e4c708c41b805b01698db62a0a58ea6ac483887e82959f84373035f52087152401ea7bf1095c97578d06d819cd66f294caca858c54c89577cb58d4dc610037498e9a70b5698e7ecb53069e9378962b02bf004ef2227a00767c5a08a68d1814a7ac56db17087052370132140fd4d2e4a376945fcef355e0c715273b90f966f146d717b09fac59bc00fe373d66d25a62dea9f4c3fcfe8a4e2824f274a7b21d8ace65047198e957c9eedb043e3df44b6abd1949bd3ef4784d5b0ab2b787a71090361f9aa31567bcb8b1c8735ee32cde7ffe26fac4e1a185daeae821ec3d04b6857627a03b5efb43c2244f0ad469b675ee0c5e6e44929cd111490f6f2b682fd36f8a111edd3b508defb62b066001593ca5e1988c81e100c8352dfb758b71d25847b10e85c675f9fcfc1da3e486086ad25594bced208ec2494a7e3417ae2c2241c7c387be52b20e7b9e5ee8853e53451dd74ceac15b890f1d50c5b99b75e1cfa4a0f1558f12b3bcb301985a16b894785995f3d0ddfb5b1c5d54e6050febea6e5cd0bbfaa33fc3ba14cf1d6a3edba247bd46dbeadc7bfb760c7e5c6fde526febf41729446cb67fbf8355336b8ac0300f1db3673d2bdabaf0ed06ea9138ceb2ee79a83da46651dbd9b31d8b326aa70ca98169c5bed21f57e3ed134cd67b9a86bcade2da465b299246986291a7ceb3819dd631cd685cbca82fc774c689fa5b0483cf73936b553adf278f2e045b3bb74f316e2c3869896467450a8945b676a71516b5ceea3630b9bdf18a7aa0be9bf94db8146904fcbfd9a6a68da31ed9957dec1b0e3b0ac480a7a5b6b1ccfb184c0d67de876c4deede41f7ed923b35c2a881b52677da1830974c1c78d77376e366103ab88afe9c7b9c4ef8b78bd479ed5f2edccbcc56d8ee41a50eaf309ff9cb5f7cb4b600116e11c2890dca14cf059dcb4b3e5605243eaed028f9f6e6d6b12f295dc28887ddbce1d39145195d01b0cffa7661efeefffc99fcedae893d1a68cf4c0fc97e814c0fd260c7ec77dafb8d615310186cee9e00fffe22638ed029b37c39b7ccbf448e60f0ece4088a8ad7a61ca826ce3bbf70fbcc55ae050eee426fb60179cc8b39aa178b2f2af79363b54b3992b4fcc18a26848c1a6ea42b7aa218b1cbee7620833fb230e1e7d7ba51d9c0789c8a1b294858c3edb8320475dc2b7106231742ba168071478b7ef4398801af4e991ca2f370115a37864d0dd9daf048da63c04bd30dfa6ede58e37ce8dd2c46162fea31d212d55f6d990cda7d89be201586deb67fffa9529b720eb959693994dafa9cc01ac29eb625dcbac9e341bc9d4b201e23f66e822aebba48a89db20f872d9570894e249c9ec85d748a42f060445a8e9ba485746f25bd5ce297a9182a83352cd1b36d1b9778ee698aff362532cae5533c63a2a6a6ad62d4de4015314bf2857c271d7e7f3022df3f6ea9cfb3548fc97bbcb05257b16efb60410df3be58d841f1966fba6aa5f9df6d6910ea55bc78b8e3961e7630a50ce0964c350ff45b996a3b11df7166aeca82c6e14f6b59cbc1f5669be9fbe07d752d1f70fd561fff7d1d2fc3f6e5d98a405cabb5dfcbf59a8a315e97bfdb7c346b5f9882deb6b3dea03f1085655a3f8d0f4d81e4d12e9eed0a711ad6349586f1884c6a2eb58b60b1b89225df4a6caf826132a700265e00fbba9d42f3a3021ffaaa2efb8f9c8d440d7baa862915ec695865402af03ab55d0baf1cb7c52c873e6d86827634dd883db6453771f43c2d208ccc8bb520ddfcd59ffa16c1531d81cb031a72a67fcd63a125ff9967f3370a388bf3a28ea3141bca58ea1b952e41b1672d748a99167e5847550b9d5826c38b051e3f0d75a933b98235959a5c642617099da60bbcd405963c22ac329849d2cb9497f8267c5ac7ef3825f83d08e71d88427f50f322fe9108ea0783f28986f835cb2fe52ff144901ee21bc0a6e7d1411d0a2165ebbd21f048f615665334c9a6a1637d6fcc2803dbc2517b92ed89e44dfcf3f933f9fe87c346f2bce2d2110f20a862747556d7ba5673fcb84428fbeb7ae18f047e91eb6cab1039aa665e72820740b96247701295f829a0f0b1e60515e987470a830201c9a516c0e9ab0e497d4450325089c153134c1a6b41811847524263dbefdfa8c26dc06218119b5fbda9e75b61d35e2cb365c54744bcf5f21885e806aa3fa79f68123626678cdafa5ceb833c35439394c5e2b3187df9b1fda2681486dbf8ceb6c75c07a4f54598c4f214bcfce3bf92eff47f9c8c5c408e8f3ca0873eaadd5a7a3cc4578201f9477a1bd6faf0740f665ef763a6938b7b907fe927af3f0b2bf0935ab53de09860979d2d287e04eb4f6467e2cd9cf64f87366dd0fbd8d96d38ebc3d27dccac172f9d4cdc83fad55730b2722e3fc673171b3398f7decc6f211a67ab785dbea93ffcf3f5eddbfbc854677f17c7d379c5ae4e9e7f61667daceacf4dc4b5d3b810c181d4b2780c138ea39b47a31f36e34bbb20228077a2554d0258256ffbc1ce491396720a56f6872b41de40199fff3afef5d78bb15707184649f9eac8e8887cdf621c9a01780d641045d118dfcd4b84320ad291ef3f1eaabad778b0538d7844cbeeb7e07cdf5711a0db4b3fdfaa4b3f6ddc2422f748af6918e422a797672b5d7ce96cc8cf333e21c1b156dc56c4d5f71f9b660e116739cdaac4e911e9aa5d0257b7d701f791fa5523b1d1d0d20590e3f841a81fa559616e7a34c04f610d08bbdc178fb68f0666e5e25ce18c205b193cfd712c463e55143ad554b1f463252a979a92ba74f4b182c1f87db3cbd7c889264596b2ab275b1c420d2342b3c588c49c1790e74c7991d9d68a6dd103b0bb92166554b1729eceb4ebe0d7295dfd1267fe5315f105813eb5d2fa673c262b4a60c95759c2022e4363d0b6175872069afd05a152beb6b425ce7a0e9da1ea0861cb9bacbf36825c743087df25457042519092c45941e3647d27f644f1b59dbfdd3ca4259108bfa8769c1665638d7ecc311be78644a7398b09c512489afcbf3def9e31535ddd06ede740dc8c41df2f1e5234d27d819b9bb66214953a56f8dff367fbfff378ff3f2f6efef678f360dcfa71a8fb48be53fa5ec8db16a2c0fef516c8ff010000ffff010000ffffb944a65489590000") gr, _ = gzip.NewReader(bytes.NewBuffer(bs)) bs, _ = ioutil.ReadAll(gr) Assets["app.js"] = bs @@ -63,7 +63,7 @@ func init() { bs, _ = ioutil.ReadAll(gr) Assets["favicon.png"] = bs - bs, _ = hex.DecodeString("1f8b080000096e8800ffec5deb76dc3692feafa7807bb2b69c15d9f225ceacdceab38ee44cb489ed1ccbde6c3627bb074da29b8848822640493db2e6d9a7aac07b932dea666b92fcb0451240a1502814be2a5c7a726fffcddebb9f7f7cc9021385d38dc93dc7d9d853c932958bc0b0cdbd87ecf1f6a3a7ecbff8919ab16f54ba603cf69932814899a76293ca596654aa5df6220c1995d22c155aa4c7c27737de6bc1d49c99406aa655967a024af982c1eb421d8b34163e9b2d81267b75f0ced166190a164a4fc450ce04dc300f92666263ae32a856c6f051b01f0ef65ebe3e7cc9e63214ee86e300dbc83d0b79bcd81d8978c4e285c3936477a497b10775c70bfa44fcaa3014e9eee8b048d9336938625ec8b5de1d61a650f1a3119214dc9f6e30368984e1cc0b78aa85d91d6566eefc75542504c6248ef890c9e3ddd1ff38ef5f387b2a4ab891b3508c4842228652072f7785bf10b572318fc4eee8588a9344a5a696f544fa26d8f5c53188c1a1972d68b83492878ef67828761fb9db2b847ca1bd542646aab8466b251bcf4ca0d2951ca18c8fa0d7429018241b2f334c7a482948c57c7734e7c7f8ea2620c8e9061630d284625a0a917d646767d8c9afa1735f434d9b0fcfcf27639babacc0129b2965b4497932f6b41e976f6e246317be8c723e5015742084b11c5ad530cb041a61c4a9c1c294c2d84cf94b76468f8c25dcf7812167a68c51d10efb7a3b397d9ea7cda1d1ce9c47325ceeb0d177223c16467a9cbd1699186db1f2c3167b9182b4b798e6b1764095e5dc9238dfa03f59f8efc157658d114f1732768c4a76d823f72b1135f2bac8ac13a958e98483f69f75f1f24ac4a1da62af54cc3df8bba762ad4021b7d8680fc68c84a1f65a9c0087259956151c940db5dbc771e34f0da9ae49a7a83aaba928affed43974487f6a49d95f4bb933b5a4ec975298a9d417a9955dace256bb42b5502d31efb0ede7cd9eae7d2132ce575587274a4b1c113ba85330268fdb15486d9c5839b30c8c8229aba2cfa4700e2a9c65ad55101a1666515c96f1a54e420e7d2963d075e1cc42e51d157c806adb910cfa58e847a93864334175aa8419f78e16295a3cac45a5c0fe62b6f9f8c9b32df6f8e936fef7e8e1f3a60453eecb4cefb027b5c617f279949cb2a7d5f742908fe1f3e3e2f379bb5da066b1eb73301c2d3d0fc51cb8ddae14bdd1bc47dbd567d27c1eca05ca1f1bf9fc625915022e0cf1aa7cb12fd83d19a1d5e4b1e91809304794c54e02698443636627562760671ac6e04458e13fdddeee24e4afd815dbfcc76055fa98f8cf48f892b3cd889fe652f9fad9d7c9e9c392543e3260924c60a083524eed97faf829333336fe12b417a64ac3382bad2583b9c8a0e115eec2dd29f3b22fa15d29d889194c8d2c0940561a8605e361a84e180a7b960a7ea471260d15144f45922a281382128d35cc71301f9f4813d4295a8d8019fecb71f9b92e57e89234e26121d8f352a126631a4430978eed64ba31a116d20c024083bd5309287bca700ac76f313f2e67627e8c29f60f1a88e2d117739e853061c24c2e289f5c709af6ec6c30f165490467390e8d4ef3349c4740af9b7538b31420cd683a91d1a24841cb33623af5702272f0cd79f4f8af34ff313b3f8f9e3c86d991d4c73e8fa7ac9c0e271ae41116c402e98309744e61be6ad66fa786cc08a8fd23080b92a69df328919be6398a966461ad1d85746a8f34e4ca86d31c5c14f05395f8ea24aea5423acf27e8bf8cdaf940fe8b05e2193408f94b9dca4b5f9afbf14c27cf27b352f6a04b50fd643c837fbc5151c579594124e2acc10df13b2d79b2f80d90e1116018df7f2b12b5f910a8d7c5b9089749803885954f4ee063cf5ac1dd171170f8c2f71916879941a54b646d32869a06578d3d33a86a68fe89b02268558f247a2b2e45238fa58f9a7b09f6c0f098436b18f4201e3db568f15714bfa460e470b97c48d10368571b807d3ad8bf15a9e82033a86483b853f3f90a6bb6f8252502e6ddf0d40c549539640f5a15bfb514baea9d8cb3b036b26ba955ca640cc222ec3c068b600d6c8f6db4f9d1227f2b536dc0b49e6c3115874b06eec049cce49cc5c2135af374f99ce57cb1139ec63805e5d63b270f1290208a7b407f2e1707311ac5d2a000e1ca143798099dc8071b5bb757b574108a0819fdefe4d5366d573baf83130ee59a044f9a29e4948ca6452b5e0be10b1f66a827d35262fd6471fe6adba964fa2e40b716db9ba53417b1806b705b05e0287e8c2e2e3854b18219dc0310cac1e0bbd564c1a20c459eb38393759e897cdd589c3449bb9371d254850b9946e05d9b03f36cc093014ead4b655fca7e9a19f0ba4dece888fee4732e4b0027e7f3caed68ba65a3c5685d4f42c1d3b93c1d75f455f343e3b5f6923fae68bc586421e00d50d0963e3734b7a08705ab49841c06b6892005e1e1c38a42a7963f5ba7e40e02ff64c4a48f82cd6b9042af57f77c689c9d61913d4cd8c427f7601ff003f515bc0a6e2c4d447ff8f707601b7bad57dcada1d4c807397b46562b1b218b06700039843cd1059e4800296028e22f8df61660043f42c3be90e0479e426356c9b750dd4530805929b9fb32151e75df4746518f1fb909cecf2f225f8d0156037696e6a1e126ab8bbe09d9eacaca57a48916a8d9136d15cf3ba7508dba549a1d51089895925ea96d88656b676cfb2ddd7d615da77a11d60a05e4efe0c8c804b16f0715a4637d85ae344c4dfb923031b8d81219de863eb5018d480488aca9c16f80f81c6be79a75b04fc12fbf97f9713ff7d76f9875e61c9588b8d5c06f29e53a2d2bc7ccb51a586084087060f84b2eb25f5d191ff350f6e9c3e0f6e7f8c0d172d116c0cb3455576d7f37b39fb3a33d1581dbd47630105704a98ae5df092e5ca3b73bacd9e76aea2254b3b6cbf037f8c6c3862f77131dbb20b2dfca506898187878c297fa7516cd447a7e4e2b0e7a8bf514fa6669a8d04cc61c87c8379f4f60818adaf2fa4179b720ae10a95e525a54e60e09cb0b55e63be8e3858ab7e3056f00baab39c1f59b91580c0ec725058645ee90bc305cdb92d22baec1c5b8ae76f5e62f30583e719060de022c7d033eea68fab3d07d40ab87c0bd1685d7ea22029f4fda19d873e11d89b6621e2c62950af6a34823a935987a7dfb32b7756295faea626f10b9cb92a778b8c3c39529d6c6c97f9226b8a24920ca9aa29828922bcfad90d28792218916153a7c8f15b7823e773b39238c6e754705925446608a463d81c8aa7503e20200563d19b6e11a50b1d1af2e0de9728fae1014a8bbf418c3ac39f324801bf3e663203ecc8d2f97386a7e3b96de9b2fd075ffa55820d87cf8ebdd71de6df30aaf1ddf1ce473488cbe8e5560f28b8bb58fbccd343aaee92f57fc5ce0298380ff7496579de59588dd8b57ecbd91e1f5bc0cbd04d410b9f0e76e001bc3f5916eb574efc7f737d7522fc960def360c4b4c01fbcc6e06da53cdc79747efe6f77140befe79fd95b6ec415250195c4c24351ea5f1e186578f800bde959823a10095073effc1cdf367bf21ec40485dfe16b5d6d1e7e6ea1654987c8de27b722309599e1120317e6e6455660ba5cb381e51771ac00ac8a37dfb37bbb2c03fb359771afc91a2c5cdc9c13a8b41dcb296a6387b8d5f06a519d0b716bb1ea88fb60a8a0ce3c5c071bad6bfd68fa86f6b50c05c72b95f83c5e88b4ace35e4f25f3f9905a3ea7356d4758ff5ba4faea36f4d896fe3d6265427305dcf9ec7079d04a13714b2b4d154ceb43acb45d18dba8efd272530762bdee3a537bcf47078d4e7c7bd54527a4908769eb60f996169dda22fa73d1a99138247226e376e4ec85ef43e3ae16bbb10a80141addff7b5c90e8d1f43f044cce1beca205b56b4f1762bf76913f32686ecb6208766e97b915087dc7f015b619285c7b7cfd09b46e222e593ddad8e4b8b935093fd172b6eede7f2730cd6ef07143112f4cc0a66cfb2e6ec47bad8cf4c4b536e0d56127341c2167adfdd8cdb481faec0cbebaef642460040316143ba3ef76a26807fcb9f3f39d629b3520b4792a45ec874b0b59b110899a46c4ed6fbeab81bdee7d7875a5a61d71561186ed6f6de38f37df7fda6d770d9d2e37a1964700f0f33774766bd8c980626b62fe0a4c0a3f3ffc5587ca1bab8abe7234a06f437d730f7dcdf4e45908d4e5f6064f03ee8ca189da5359aa855b9e40746361c6a3e96196e0a1113666dfaa348b5637f70eaa42431d0b69826ce602e81a7b3c8c827159d53815d0611a571b7e002dd786bdb51fae58db9a0679407fa1d2e5d8575e86e02f3f8ab15f7fbd9d464aad336ce23759d76ef51ba8013acb9e58ddebd8afbf7e9f352d26812fa8d2236b8958a47c000e853a971e95cd43e3b71cff36eb9cfba2436f29d1f1250fd5a2d382db0cf9f9ce1e2b6ef3a0658691c7433a5b84ff1791a7c6000f9e368b75b9dd179a1d710a8911694373635683cc5e89c0ecdcd6b033c1d31e33d3d5b69569629234abaab65f6b017610f75dcf044340bfc5a0bb306041a794394b52059025a263516c091ac10e40b629741dab10a3db20fe1680e51268df0f4418caf2c899e53c196c2d1b66d36e39a67dd2b469bc539fd232c35dd02619cfd52de8527b0f794bf485043e89f248cd2a99bbec4732b32c50a17fd37d5f1c43e9e9f9e290cb5de8f722487ef35d5f3f9dd3ec91423a78fa3e14467c92deaf4e7940f5643cdc9beaee83fd9e8e96fe872b4c15969813de4c6fdf42cfb64e85350ad3b68c03807246cea5670fd8dc8f7cae83e7f5706ab52da21951bd76ffd7b29cc0a066f81f42f2d6d17e7ac5b5dd15b87f76162da1433f322fc8e223dc1ebed687c083a8c516692857f6b6a56d8f4b33c8e400728966310707d59e55fd908e57ab1a8d2fd1f80e6f65d041a1d233a1103ba045dc9396131d742c2852c7ed0dab7ba142c8da764e2e3b92487bd0f7ef45614560e0ce0d2bdcc51ea893ddd13d64112ccecb53f0685766f762c455674beb0adf2235881246383a485d61eccc551ae547b5f17194df438283f625f5c99af5202c50eca0228f97be9e3d00b3eb10aa7e8067cf0b426e4cb13af78b7c6b3ebb7fbf2bd597a959ae2eef4c423e13219e9eb7ccc1b09b5abbb30fb01fd3564ac838c1637df922ed8a5cab86e2102ed64f6ac3999a97df49d3b225a3da4d27d476da100c16204b71f10a19cb4393785dca874ce27e446ab58395481f4612b1d7b9045384887a34618d8da3d0ea0a0f756bd319c89b24056d00458935605dcb3ef5bda21d5d67bbf5e3c7ae6e4d526a057088873163db7388eac9663282f3f62e21d6b84b6844aa3e65f90164306076602b9b6c2f3a42722e3b440968baff08e71e7c04a28aeedc0173b129695fabffd05d6958ad693de379fa530030c2de31013e079efac44ab7d8911009f21a49a8966e449a88684af729c5343ee1cd9e2085964179d08306eb5a82248c526effaa60cff70b3a8306a05b2adf9ac1d6ec12e8043c090bdcce421e1ff5f335a87e5289d7a4f217b340aa00bc16acf84a683a961b2a7564878fcb0e0c9e06cc429f04cabe7a4c573f710fb508170fa17f3c5c89a47ec39301803621cdea454c9bb9f4967516f58ac2cc0415ca55a6a7edad18637744b9db4caeb56a1cb75922525a6fd09210b80ee8a8d8eee83b15153b6c721b8654ba2cd82093c5ed4ecf6ed3d469240eed01f4581b982251dcb9512ec6af1766da760dae0db60f47df94ecb85da4c570d38be2f11252f4972036e99158001be11288df65ccd9ee2eb3880f455d557a557997bc1e9af492727f496613577439d32281116060e4745c5f524d0d32d9c1d066b191b7641fe3296b0be6e2290a82d14e444ac081674661d4c8631480042d5cdaebe444417e408f4fc648eb1380e072eda976f7043f16f9cd18cdceaf59aa2fca838f978fde1f02fdaef8fd5d03ed1547dde0038d7731291e8a703eba80738a53dafb08f0c87d5de4300ac0ff1f7c1d094cac597bcfef3e91b8beeb8147202e763d30d7efc1f5a81ffeba1107a48fe0cdb921783ce54237a4be56da95deb566da956f883b5331e4e263cb9de948ed7167a8eeda0466b3e3ad278d33ee9d331895cd9d9b524a382935e7b47c8547b70cdb4af716d715f4783e17cc636fed19c89a9b93c5f243863bc2606c41f68423fc8a7747e3fffb853b7f7fe1fcefb6f31fceffbbbf9e3dda7af6f4fc8b71efc447ed1ce69950d6f669b8564f94de49475ae59d1ce24d1320131bcc021b36b7ab0dacbcfc62e9b257399ec7ef1aba0021bdbd50cc821ddab9d88b9c87306bd1b31525d91f02c8695d3b4aafc2e6ba81eaeace429f2a773132d46518ce49ae349765a4f4b3ec8521f56edc7cf6b4721408f284804e1e76fb0a5b85a340be01f632fe9b6004740aaa3b19d353835e1c2ed7b47b0504d98fdd7b6aae6792f096947546c9a65fc22c61818661c20f97314d44a0699cfe31deafcc5361806cbe2b9aa0f2e68bca127d02bb6285d967596c6a655bf01dd173d39c14f1003a758f881e5816a9cb7e9260514099bd5410b69773264de5130b34e02ec341602448b5e6065b45fd47a9a636ac92e1265bae8bc1817708a36db399cb1350440bc344f4f9ca43d936fd42b35253c695f19ca0b4869b96e1436cc806b02b218c67c30146670bea14f148f94c9df6e964efe8a3543b02eda02929f50c9cea907dfdc62c7b5f4077dd6b867eb745eb1b6ef696050cd2252978741e6af93c5511aa32f80f9a45007d717854513e30cd78575b3b431173b3e1368a1f9de4c347e361be72d06953f8a7f95cbdea9fae69c89defccc6d17db67a03c127e8508c0de4d5b19934b67ff3d02b3bc1282a46f370be45eb9377a4cbe822fa987dfbe29dbd6583ac5147f4600d5797e99dd66a8246e0878ce29d0114c2ea0b1fb52b6af448fd68cd05e76a9a9cdc48e76bf08a710c5185b443bad81e3d5a39b6dd7da6e52675e190b8b1772422433806e95a05fb630335438fb1d84b7474f7c7df8935d612b747e038caf78ad3e203a381557df964761903483ef61ceec6c5186e94e0429665846ea9e6398070b5293e17b8c35e7466c73c7437e23f1f81b70d00d1ef4a549b156f08212314b9509e43a0b42df8bd10491f98aee71808a7ab22a329fe5f74e95a635387d33502765751ed7d0d70b6decc7a9db3444aac164970d91fddb66f5e9761178aaea7b75610edb17c98cc41cb2a8d0455c515b92d9c85ecef8f5c05c1d6ab5d8b615774a0cd5cc958e59ae689e859de84e3bcca2b74ddc56cfeac32cb132d6072c370671c80a358143c5f116b5f016cb71700aa65f0bed5d806bdd5a5d96a72e95aa0c529a91167c35d82e41d214c94352744d2b4b510043f67747634ce833be8782dc9467ab8a3105026fe94c5b1a07e25c146dc7801b869e09385cbb23486892c858d5e897cea0590fcb6f6669cb0a63e7f2e80e0a471cd058fc157e2dfe68247717b7cdf26d53cf9cead76742d41b0ea2afc1b5e7cf8948180badb50fc660858abb2277aa16971c185cde8a276e2f2f4030c923dc0697425c54e3c0fd682588b53cece8ac278832add8f93bfd3cf586178680de4cd110b2a548bd03a8c5265c5f7fcae8202add005eb2e1ec5800c6f127b06b422fdeb7a9cd28b7efbfcb84ec1ce940ad70bafcf035811df3a11adf113ae2585ab38089fcaffea19048b4c1edede38e84c4b803510b0ffaf3f4afef6fee00f3e422e2381db1c1d776ec3cba57e82e65f16d10dc646f8687f9cd1eed2072887bf35413f78f89b4562943a6d67fced4326d2a5f3d8dd769f5c9cbbfa5dc5dfda3fabb8b61c4f925606682b9ddf07e0433f0afa4f000000ffff010000ffffaadbd6dc25740000") + bs, _ = hex.DecodeString("1f8b080000096e8800ffec5d7b77dbb692ffdf9f02e1ed2676d7a4ec244dbb8eacb3ae9db6de368f1327dbedf674f7402424a2260986006deb3abe9ffdce007c3f245ab613dfb67f2416096030180c06bf193c387e70f4faf0dd2f6f5e105f85c16463fcc0b6370e45bc48f8dc5764f3708b3cded97d4afe8b9e8a29f956247342238f08e5b384b82252099fa64a24d22107414074294912265972c63c67e3bd6444cc88f2b92452a489cba094c7083ccec5194b22e691e902689297c7ef6ca916012301775904e5944f15712169ca366622856a79042f19f9e9f8f0c5ab931764c603e66cd836b08ddc938046f37d8b451689e6368de37d4b2e2217ea8ee6fa95e65704014bf6ad933ce550258145dc804ab96f61a640d0530b4932ea4d360819874c51e2fa34914ced5ba99ad9df586582af546cb30f293fdbb7fec77e7f601f8a30a68a4f03666909b1084a1dbfd867de9c55ca453464fbd61967e7b1485425eb39f794bfefb1331083ad1fb6a1e15c711ad8d2a501dbdf75765a843c26dd84c78a8ba842ab958da6ca17492b47c0a353e8b5002406c9ca4d15e12e52f21336dbb766f40c1f9d180439d9c0028aab804d0a21928fe4f2123bf91574ee2ba86973ebea6a3c32b98a0a0cb1a9104aaa84c62357ca51f1e4843c72e08d95f181aa207dc694e1d0a8865ac4d008c52e1416d629844c85b72097fa272131f53c60c89e0aa544b847bede892f9e67693368b43da3210f167bc4fa8105674c719792572c65d636295e6c938304a4bd4d248da40daacc6786c4d586fe9306ffee7f55d418d264ce235b89788fec3a5fb1b096d74166ed504442c614b4ffb28b97972c0ac436792922eac2df431149010ab94dac4318331c86da2b760e1c16641a55505036d46e0fc78d37515a75553241d569a7a2bcfa5367d021fda905656f29e5ced482b25748612a128f25467691881aed0ac45c34c4bc47769ed77bbaf24693b1bf2a3b3c1692e388d8439d823179d6ac804b6547c29ea660145451957ead15ce468533ac350a42c382348c8a321e977140a12f7904baceec6920dcd39c0f506d3392411f73fd281447db4c509d32614addd37982160f6b1109b03f9f6e3e7ef26c9b3c7eba83ffed6e3daf4b30a11e4fe51e7952697c2e9fddf8823c2ddfe7827c0caf1fe7afaf9aed02358b1c8f82e168e879c066c0ed4ea9e8b5e6edee94afb5e6d380cf51fed8c8e7ab65950b3837c46df9625f90073c44ab4923d53112608e288a9dfb5c315b8f99bd489c839da91983736684ff7467a79390d7b22ba6f98fc1aaf431f19f21f338259b21bdc8a4f2f5b3afe38bad8254363260928c61a083524ecc9beaf829321332fa12b417a64a452829ac2581b948a1e165cedcd92bf2922fa15d09d889294c8d24f64156128605a14120ce090a7b9a307a2a71260d04144f589c08281380128d24cc71301f9f73e557291a8d8019fecb51f1ba2a57e89224a4412ed8ab42a1c6233d88602e1d99c97463ac5ba86710001ae49d8841d913825338be8be8593113d3334c317fd040e43f3d36a369001326cce44ce7e373aaa73d331b8c3d5e10c1598e42a3932c0de711d0eb7a1df6340148634dc63c9ce72968792c22131727221b9fecddc7dfe8f98f98f9d97af2186647ad3ee6f768428ae9702c411e414ecce71e9840fb02e6ab7afd666a481583da3f82b02069d2398f6a72932c47de9234a8b423974ee5a71e7245c3f51c9c17f012117be23caaa4423acd26e8bf59cd7c20fff91cf10c1a84eca14ae585c7d5c3682ae3e7e369217bd025a87e3c9ac23f5aaba8e4bca82064515ae346f33b297832f80d90e1296018cf7bcb62b1b905d4abe29c078bd8479c428a5fb6ef61cf1ac13d64217078e079048bc3cc209205b2361e414d83abc69e19543534ff9c191134aa4712bd1517a2e167dc43cdbd067b6078d489310c72108fae9837f8cb8b5f53307cb85c3e24e80134abf5c13e1d1fdd8954a49f2a54b241dc89d9acc59a297e4d89807957345103556506d9fd46c56f0d85ae7ac7a334a88cec4a6a99321e81b034761e81453006b6c7369afc6891bfe38954605acfb7898882050177e03c227c4622e6322969b2784e32bec8394d229c8232eb9d9107097010c503a03fe3f3e3088d6261508070698a6bcc0476e8818daddaab4a3a08850544ff6f67d5d66d5733af8d138ece35f69fd453b453624df256bc62cc631ecc504f2685c4fac9e2fcd5b453f1e49d8f6e2db6374df45c447c2ac16d6580a3e819bab8e050450266701740280583ef94930509531479c60e4ed65926edeb46ecbc4eda198fe2ba2aac641a8177650eccb2014f0a38352e957928fa69aac0eb56912d43fd279b73490c38399b57ee46d30d1b0d46ab7a12309accf885d5d157f517b5c7ca43f6b3a5f16c9e06803740411bfa5cd3dc9c1e162c2711ed30904d0429080fb74a0a9d5afe6c9992db08fc638b700f059bd5c0995caeeed9d0b8bcc4228798b089bf9ce323c00fbaafe09151656822fac3bf3f01dbd86bbde26e0ca55a3ec8d933b21ad934b2a801079043406399e3891890028622fe566b6f0e46f02534ec0b0e7ee40534a64dbe81ea56c10062a4e41cf184b9bafb3e121df57843957f75b58a7c39064805d8199a278aaab42afa3a64ab2a2b6d49132d50bd279a2a9e754eae1a55a9d43b2217302924ddaa6d88656b666cfa2ddd7d615ca76a11d2080564cfe0c8f018b16f0715a4637c85ae344c4dfa9230d15f6d89146d429fca804624024496d4e0d5407c86b533cd3a3ed2c12faf97f9513ff7376f9871e66c11b3a8d1c0ef74ca4d5a568c991b3530c70821e0c0e0d74c64bf393c3aa301efd387c1edcff0812df9bc2980174922d66d7f37b39fb3a35d1182dbd474301057f88988f8df355cb8416f7758b3cfd5d47920a64d97e17b7847839a2f771b1d3bd764bfe301933031d0e09c2ee4ab349cb2e4ea4aaf38c86dd253e8db85d285a63ca23844befd7c02f345d894d74fc2bd03710548f59ad2d265ee91b0dc40a49e8d3e5e2068335ef01aa0bb9869b87e3b128bc0e1b8a6c0b0c83d9217866b1b527a4925b81837d5aedefc3906cb260e2d98b7004b5f838f6a4d7e61b20f68f51078d0a0f04aac22f0f9a49d823d67ee296b2ae6f13c1209236f58127229c1d4cbbb97b9a913ab94eb8bbd46e43e4b5ec7c36d1ab4a6581327ff992b7f4d93a0294b1dc54491ac3db7424a1f4a8624bda8d0e17bb4dc0afdbadbc9b130bad51d1588131e8229b27a029165eb06c40500acba3c68c235a062a25f5d1ad2e51ead1114a8baf418c3ac38f35a00b7e6cd47407c981b5f2c7154fc762c7d389ba3ebfe6bbe40b0b9f5dbfd71de4df372af1d9f6ce473488cbe8a5560f28bf2b58faccd7a74dcd05f2ef959e1298380ff7296dbce722b6277f092bc573cb899972117801a4207fedc0f60a3a83c958d961ebe797f7b2d75e314e63d17464c03fcc16304de564283bdddabab7fbba758f8287b4dde52c5d694045412311745297f7da484a2c123f4a6a731ea40c840cdddab2b7cdaecc97b1c6928fc0e1fab6ab3f5b98596c61d227b1fdf89c044aa864b0c5c98db17598ee932cd06960fa248005865af7f240ff6490af66bc6a35e933558b8b839c71749339693d7464e70abe17a519d95b8355f75c47d30baa04c5d5c07b396b5de9abcd6fb5a8682e356251e8de62c29ea78d053c96c36a496cf694d9b11d6ff66895cdf869e99d27f44acacd15c0e773e3b5c1eb4d2a4b9d52b4d254ceb43ac7abb30b651dea7e5a60ec47ad375a6e69e8f0e1a9df876dd4527a4908569ab60f98e169d9a22fa6bd1a996382472c6a366e4ecc0f3a071ebc56e8c0220855af7ff1117247a34fd4f0193b3063b6841cddad34aecd72cf26706cd4d590cc1cecd327702a1ef19bec23603851b8fafbf80d66dc425cb9f263639aa6f4dc2577a395b76efbf63986636f838018be6ca2713b2731f37e2bd128abbec461bf0aab0131a8e90b3d27eec66bd81faf212de3aef78c860040316647bd60f7b61b807fedcd5d55ebecd1a10da2ce12cf2828581ac58488b5a8f88bbdf7c57017bddfbf0aa4aad77c4194518b6bfb5893f5efff869b7ddd574bad8845a1c01c0d7dfeab35bc34e06e45b13b347609279d9e1af2a54de682b7aeb6840df86fafa1efa8ae9c9b2685097d91b3c0db83782264a57a489644e7102d189981a59939334c643236444be13491ab637f70eaa42421d73aefc74ea00e81ab93408fd5151d52861d06112571b7e022d978abc352fd6ac6d49835ca03f17c962e4093745f0971dc538aa3ede4d23b9942936f1dbb46bb7fa2dd4009d654eac1e76ecd75fbecf5a2f26812f289253638948283c000eb93a171e95c9a3c76f31fe4dd619f55887deea44dbe33410f34e0b6e3264e73b7bacb8c9839619461e0df4d922fc3f8f3cd506b8ffb45eaccbed5e6976d80524865a1bea1bb36a640e0b0466e6b69a9df19ff69899aeb6b5a689715cafaadc7e2d19d841dc773d650401fd3681eec280853ea54c499c08802ca13e164516a011e418649b40d79112313a35e26f01582e80f6439f05012f8e9c19cee3c1d6b26636cd9663bd4f5a6f1aefd4a7a4c8701fb48947337107bad4dc43de107d2e814fa23c5c9252e60e79a3cd2cf145e0dd76dfe7c7507a7a3e3fe4721ffa3d0f92df7ed7574fe7d47b24970e9ebe0f98629fa4f7cb531e50bd361ece6d75f7f1514f4773efc31a5385216607b7d3db77d0b38d5361b5c27a5bc6314039c567dc35076c1e861e95fef36a38b5dc16518fa8deb8ff2b59ce615013fc0f2179e368bf7ec4b5dd16dcbfbc0c17d0a11f89eba7d1296e0f5fea43e041d47c8b34942b7adbd036c7a50964b201b984d38882836aceaa7e4846edaaacd1351adfe1ad0c3a285478263ac40e6811f7a46544071d0b0ac55973c3ea612010b2369d93eb8e24ad3de8fbf7a2b03c3070ef8615ee62f7c5f9bef50059048bf3e2023cdad6ec9e8fb8f26c6955e11ba40651c2084707a935c6ce4c246176541b7f5ad93d2438685fe83e59b21e8405f21d54dae3d56f2f1f81d9b535aa7e8467cf73424ea46375ce17d9d67cf2f06157aac713b5682fef8c033a65019e9e37ccc1b09b18bb7304b01fd35a257814e3b1be6c91b625d7b2a13884f3f593ca70d6cdcbeea469d812ab72d3896ebbde100c16204d70f10a19cb4293785dca8794e37e44dd6a1b2be11e8c24cd5ee7124c1e22ead18425364e87565b3c54ad4d67206f1ce7b40114c5c680752dfb54f78a76749de9d68f1fbbba354e742b80433c8c19999e4354af6d26d170dedc25446a7709595ad527243b800c06cc0c6c6192cd454748ce21272801a9ef3fc2b9077f0251a1efdc0173b1c9f5be566fcb6935acd2b49ef13cf9d9071861ee98009f034f7d62a5dbe494b118790d3954ab6f441ab370a2ef538af4f884277382145a06e5410f6aac4b0e92504238fdab823def5774861e804ea17c4b065bbd4ba013f0242c703b0d6874dacfd7a0fab54abcd22abf9a05ad0ac06bce8a2798d4c77203214ecdf071c8b1c2d38069e0698192af1eebab9fa88b5a848b87d03f2eae44ea7ec39301803621cde845a43773c96de32cca96c24c992e94a94c4fdb1b31c6ee8872b7995c6ad5286eb344a4b4dca0c50170edeba362fbd60f22cc77d864360ca97459b041268b9a9d9edda6a9d3489c9803e891543045a2b833a39c8f5f3748a5e91a5c1b6c1e8ebe2dd951b3488be1a683fce735a4e82d406cdcd562016c844b205e973127fbfbc4203e147559e9baf22e783d51c935e5fe429b4d5cd1a544b21846808291d3717d493935f0780f439bf946de827d8ca72c2d9889272f08463b6689060e345502a3462ed10148d0c285b94e8ee5e407f4f87884b43e01082ed69e2a774fd03396dd8c51effc8aa5faa238f878fde8fd09d0ef8adfdf37d05e72d40d3ed078e793e2090b66d60ace759cd2dc478047eeab22875100feffe0eb4860624d9b7b7e8f34899bbb1e780462b5eb81b9fe08ae47f5f0d7ad38207d046fcf0dc1e3292bdd90ea5a69577ad79a6957be21ee4cc990833f1bee4c476a8f3ba3ebae4c60263bde7a523be3de3983e9b2997353480927a5fa9c96adf0c886616b756f7e5d418fe7b3621e7b6bce4056dc9c34e21f52dc1106630bb2c714e157b46f8dfeef576afffdc0fedf1dfb3fecff777ebbdcdd7ef6f4ea8b51efc4a7db39cc33d1599ba7e11a3d5178271d69a5777282374d804c4c300b6cd8ccac3690e2f28b85435e66781edf4be80284f4e642310376f4cec55ee43c8459839e8d28b5fdd10039a96a47e155985cb7505dd559e853e52e4686ba0cc339c994e6ba8c147e96b930a4da8d9bcf9e968e82863c01a093ad6e5f613b7714b46f80bd8cffc618019d80ea8e47fa578d5e142c96b4bb0582cccbee3d35373349784bca32a364d2af6196b040cd30e18beb98264da06e9cfe313a2acd536e804cbe354d5071f34569893e815d31c2ecb32c26b5b42df88ce8b96e4ef278803e758f881e586689437ee660514099dd84696ccf6784abd2276668c01d82834071906ac50d368afa8f424d4d5825c54db654e68303ef1046db66321727a0342d0c13e9d76b0f65d3f49566a5a28cadf11ca3b4869b96e1436cc806b0b510c6b3e100a3b305558a78a47c2a2efa74b277f4e9543302cda02928f50c9cf2907df5c62c735f4077dd4b867eb745eb1b6ee696050cd2c50978742e6af92c1121aa32f80f9284007d717894513e30cd78575b33431e7333e1361d3f3acf868fc4c37cc5a0932af74fb3b9baed9f2e69c8bdefccdad17dd2be81e0137428c606b2eac8942bd3bf59e8959c631415a37938dfa2f5c93ad221fa22fa887c77f0cedcb2a1ad5147f4600957d7e99dc66a8244e0878ce29d013a84d5173e6a5654eb91ead19a15e76aea9cdc4ae74bf08a710ce90af50ee97c7bb4d53ab6dd7da6e53675e1447363ee484486700cea6b15ccc7062a861e63b1d7e8e8ee977f106b2c396e8fc07194ed15d78b0f440facf2cd27b3cb1840f2b0e770372ec670c31817b20c23fa966a9a010847aafc758e3bcc456766cc437723fef310789b0090feae44b959f1961032429195f21c02a54dc11f198bfbc07435c740385d16b126f87fdea54b8d4d154e5708985d4595e725c0d97833cb75ce1029b05ac8c165dfbd6bdfbc2ac32e145d4d6fac209a63f930998396951a09aa8a2b72db380b99ef8fac8360abd52ec5b02d1d6832573056baa659227a96b7e138b77985ae5bcde62f22353ce9054caa08ee8c037014b19ce735b1f61a60bbb900502e83f7adc6d6e8b59766cbc9a56b8116a7a45a9c0d77096aef086122af38215c4f5b73a6e1e7549f1d8db2e00e3a5e0b6d235ddc510828133f6571c674bf6ac18654b93eb869e093058ba23486890c858d5e897cea0590ecb6f67a9cb0a23e7f2d80e0a471c3058fc157e2dfe582477e7b7cdf26d52cf9dead76742d4190f22afc5b5e7cf8948180aadb907f3304ac55d113bdd034bfe0c26474503b7179fa1106c91ee134da4a3113cfa3a520d6e094cbcbbc30dea0aaefc7c99ef567ac303cb404f266880515aa4168194629b3e2737657418e56f405eb0e1ec5800caf637306b424fddb729cd28b7efbfcb84ec14e8508960bafcf0368896f998896f8093792c23a0ec2a7f2bf7a06c13ce52777370e3ad362600d04ecfdeb8f92efdf1fffc947c87524b0a6fbbc4c0169cc4fd962853cda0ddf2cbe56b2e2689f1a9dedd8dfd8bb4f6da8c986aae4e8c993afacc97b49e7fa38dcd672fd1bb66b3e3bacdf2f561c46966df5ec2ccdeabafeb72c6a1895a98337c73fb2c5668b130054dfb38825b40b1dadecc1b597073ef796a56b7d44e85f16930f46b7f8d37c5ed39cb300308e5f0bd19facfcdd60699d3a6966fcfd43ca9285fdd8d9719eacce5d7e19f3f7e687319796a371dcc8006dd537300074d59f75fd27000000ffff010000ffff7b256a4ae7750000") gr, _ = gzip.NewReader(bytes.NewBuffer(bs)) bs, _ = ioutil.ReadAll(gr) Assets["index.html"] = bs diff --git a/cmd/syncthing/gui.go b/cmd/syncthing/gui.go index d98e16a9..0f866fd7 100644 --- a/cmd/syncthing/gui.go +++ b/cmd/syncthing/gui.go @@ -321,6 +321,10 @@ func getQR(w http.ResponseWriter, params martini.Params) { func basic(username string, passhash string) http.HandlerFunc { return func(res http.ResponseWriter, req *http.Request) { + if validAPIKey(req.Header.Get("X-API-Key")) { + return + } + error := func() { time.Sleep(time.Duration(rand.Intn(100)+100) * time.Millisecond) res.Header().Set("WWW-Authenticate", "Basic realm=\"Authorization Required\"") @@ -358,6 +362,10 @@ func basic(username string, passhash string) http.HandlerFunc { } } +func validAPIKey(k string) bool { + return len(cfg.GUI.APIKey) > 0 && k == cfg.GUI.APIKey +} + func embeddedStatic() func(http.ResponseWriter, *http.Request, *log.Logger) { var modt = time.Now().UTC().Format(http.TimeFormat) diff --git a/cmd/syncthing/gui_csrf.go b/cmd/syncthing/gui_csrf.go index f7a39f5a..7fb67e19 100644 --- a/cmd/syncthing/gui_csrf.go +++ b/cmd/syncthing/gui_csrf.go @@ -22,6 +22,9 @@ var csrfMut sync.Mutex // the request with 403. For / and /index.html, set a new CSRF cookie if none // is currently set. func csrfMiddleware(w http.ResponseWriter, r *http.Request) { + if validAPIKey(r.Header.Get("X-API-Key")) { + return + } if strings.HasPrefix(r.URL.Path, "/rest/") { token := r.Header.Get("X-CSRF-Token") if !validCsrfToken(token) { diff --git a/config/config.go b/config/config.go index d4f64f5c..865bf5c5 100644 --- a/config/config.go +++ b/config/config.go @@ -123,6 +123,7 @@ type GUIConfiguration struct { User string `xml:"user,omitempty"` Password string `xml:"password,omitempty"` UseTLS bool `xml:"tls,attr"` + APIKey string `xml:"apikey,omitempty"` } func setDefaults(data interface{}) error { diff --git a/gui/app.js b/gui/app.js index 4de85a6e..ac77fdb7 100644 --- a/gui/app.js +++ b/gui/app.js @@ -52,6 +52,7 @@ syncthing.controller('SyncthingCtrl', function ($scope, $http) { {id: 'User', descr: 'GUI Authentication User', type: 'text', restart: true}, {id: 'Password', descr: 'GUI Authentication Password', type: 'password', restart: true}, {id: 'UseTLS', descr: 'Use HTTPS for GUI', type: 'bool', restart: true}, + {id: 'APIKey', descr: 'API Key', type: 'apikey'}, ]; function getSucceeded() { @@ -514,6 +515,10 @@ syncthing.controller('SyncthingCtrl', function ($scope, $http) { $http.post(urlbase + '/config', JSON.stringify($scope.config), {headers: {'Content-Type': 'application/json'}}); }; + $scope.setAPIKey = function (cfg) { + cfg.APIKey = randomString(30, 32); + }; + $scope.init = function() { $http.get(urlbase + '/version').success(function (data) { $scope.version = data; @@ -593,6 +598,18 @@ function decimals(val, num) { return decs; } +function randomString(len, bits) +{ + bits = bits || 36; + var outStr = "", newStr; + while (outStr.length < len) + { + newStr = Math.random().toString(bits).slice(2); + outStr += newStr.slice(0, Math.min(newStr.length, (len - outStr.length))); + } + return outStr.toUpperCase(); +} + syncthing.filter('natural', function () { return function (input, valid) { return input.toFixed(decimals(input, valid)); diff --git a/gui/index.html b/gui/index.html index 1cbbbc73..c0210b36 100644 --- a/gui/index.html +++ b/gui/index.html @@ -595,6 +595,11 @@ found in the LICENSE file. {{setting.descr}} +
+ +
{{config.workingGUI[setting.id] || "-"}}
+ +