From 88209d88236c3d865a9f5174a0dced31920859bf Mon Sep 17 00:00:00 2001 From: Tyler Murphy Date: Thu, 26 Jan 2023 17:29:16 -0500 Subject: i did things --- public/404.html | 18 +++ public/css/404.css | 20 +++ public/css/console.css | 60 +++++++++ public/css/header.css | 55 ++++++++ public/css/home.css | 182 +++++++++++++++++++++++++++ public/css/login.css | 47 +++++++ public/css/main.css | 307 +++++++++++++++++++++++++++++++++++++++++++++ public/css/people.css | 44 +++++++ public/css/profile.css | 121 ++++++++++++++++++ public/fonts/facebook.otf | Bin 0 -> 25740 bytes public/fonts/sfpro.otf | Bin 0 -> 298944 bytes public/fonts/sfprobold.otf | Bin 0 -> 334728 bytes public/home.html | 17 +++ public/js/api.js | 63 ++++++++++ public/js/header.js | 25 ++++ public/js/home.js | 233 ++++++++++++++++++++++++++++++++++ public/js/login.js | 29 +++++ public/js/main.js | 22 ++++ public/js/people.js | 65 ++++++++++ public/js/profile.js | 88 +++++++++++++ public/login.html | 170 +++++++++++++++++++++++++ public/people.html | 15 +++ public/profile.html | 17 +++ 23 files changed, 1598 insertions(+) create mode 100644 public/404.html create mode 100644 public/css/404.css create mode 100644 public/css/console.css create mode 100644 public/css/header.css create mode 100644 public/css/home.css create mode 100644 public/css/login.css create mode 100644 public/css/main.css create mode 100644 public/css/people.css create mode 100644 public/css/profile.css create mode 100755 public/fonts/facebook.otf create mode 100644 public/fonts/sfpro.otf create mode 100644 public/fonts/sfprobold.otf create mode 100644 public/home.html create mode 100644 public/js/api.js create mode 100644 public/js/header.js create mode 100644 public/js/home.js create mode 100644 public/js/login.js create mode 100644 public/js/main.js create mode 100644 public/js/people.js create mode 100644 public/js/profile.js create mode 100644 public/login.html create mode 100644 public/people.html create mode 100644 public/profile.html (limited to 'public') diff --git a/public/404.html b/public/404.html new file mode 100644 index 0000000..04ddadc --- /dev/null +++ b/public/404.html @@ -0,0 +1,18 @@ + + + + + + + + XSSBook - Not Found + + + +
+ + Page not found. +
+ \ No newline at end of file diff --git a/public/css/404.css b/public/css/404.css new file mode 100644 index 0000000..38035a4 --- /dev/null +++ b/public/css/404.css @@ -0,0 +1,20 @@ +body { + background-color: #f0f2f5; +} + +.error { + display: flex; + justify-content: center; + align-items: center; + width: 100vw; + height: 100vh; + flex-direction: column; +} + +.error .logo { + font-size: 100px; +} + +.desc { + font-size: 40px; +} \ No newline at end of file diff --git a/public/css/console.css b/public/css/console.css new file mode 100644 index 0000000..bc07969 --- /dev/null +++ b/public/css/console.css @@ -0,0 +1,60 @@ +body { + margin: 0; + padding: 0; + background-color: #181818; + display: flex; + flex-direction: column-reverse; +} + +@font-face { + font-family: sfpro; + src: url("../fonts/sfpro.otf") format("opentype"); +} + +div { + background-color: #282828; + font-family: sfpro; + margin: 15px; + margin-bottom: 0px; + border-radius: 5px; + padding: 10px; + width: calc(100% - 50px) +} + +span { + display: inline-block; + padding: 0; + margin: 0; + color: #ffffff; + font-family: sfpro; + margin-right: 10px; +} + +.json span { + display: inline; + margin: 0; +} + +.key { + color: white; +} + +.value { + color: white; +} + +.boolean { + color: aqua; +} + +.null { + color: blue; +} + +.number { + color: yellow; +} + +.string { + color: #4ae04a +} \ No newline at end of file diff --git a/public/css/header.css b/public/css/header.css new file mode 100644 index 0000000..a491f33 --- /dev/null +++ b/public/css/header.css @@ -0,0 +1,55 @@ +#header { + height: 3.5em; + background-color: white; + position: fixed; + width: 100vw; + box-shadow: 0 2px 4px rgba(0, 0, 0, .05), 0 8px 16px rgba(0, 0, 0, .05); + display: flex; + align-items: center; + justify-content: space-between; + z-index: 5; +} + +.spacer { + margin-bottom: 5em; +} + +#header .logo { + position: absolute; + font-size: 2.5em; + padding-left: .5em; + padding-top: .2em; +} + +#header .buttons { + flex: 1; + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; +} + +#header .buttons a { + padding: 0px 50px; + height: 100%; + display: flex; + align-items: center; + justify-content: center; + color: #606770; +} + +#header .buttons a:hover { + background-color: #dddfe2; +} + +.selected { + color: #1778f2 !important; + border-bottom: 3px solid #1778f2; +} + +#header .pfp, #header .pfp img { + position: absolute; + right: 1em; + top: .5em; +} \ No newline at end of file diff --git a/public/css/home.css b/public/css/home.css new file mode 100644 index 0000000..33d72c0 --- /dev/null +++ b/public/css/home.css @@ -0,0 +1,182 @@ +body { + background-color: #f0f2f5; +} + +#posts { + display: flex; + flex-direction: column; + align-items: center; +} + +.post, .create { + width: 40em; + height: fit-content; + background-color: white; + border-radius: 10px; + padding: 15px; + box-shadow: 0 2px 4px rgba(0, 0, 0, .05); + margin-bottom: 1.5em; +} + +.post { + padding-bottom: 0; +} + +.create { + display: flex; + flex-direction: row; +} + +.create button { + all: unset; + background-color: #f0f2f5; + border-radius: 3em; + margin-left: 1em; + flex: 1; +} + +.create button:hover { + background-color: #e4e6e8; + cursor: pointer; +} + +.create button p { + margin-left: 1em; + font-size: 18px; +} + +.postheader { + display: flex; + flex-direction: row; + margin-bottom: .5em; +} + +.postbuttons { + display: flex; + flex-direction: row; +} + +.postbuttons>span { + flex: 1; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + padding: 7px; + border-radius: 5px; + color: #606770; + margin: 3px +} + +.postbuttons>span:hover { + background-color: #e4e6e8; +} + +.postname { + margin-left: 1em; + display: flex; + flex-direction: column; +} + +.icons { + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAMaCAMAAABESx1iAAAC/VBMVEVHcEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcHiEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD3uSgcHiEAAAAcHiEAAAAcHiEAAAAcHiEAAAAAAAAcHiEcHiH3uSgcHiEcHiEcHiH3uSgcHiEcHiEcHiEcHiEcHiEcHiEAAAAAAAAAAAD3uSj3uSj3uSgcHiH3uSgAyIL3uSgAyIIAyIIcHiEAyIIAyIL3uSj3uSgAyIL3uSj3uSgcHiEcHiEcHiH3uSgcHiH3uSgAyIIcHiEAyIIAyIIAyIIAyIIAyIL3uSgAyIIcHiEAyIIAyIIAyIIAyIL3uSgAyIIAyIIcHiEAyIIAyIIAyIIAyIIAyIIAyIIAyIIAyIL3uSgAyIIAyIIAyIIAyIIAyIL3uSgAyIL3uSgAyIL3uSgAyIIcHiH3uSgcHiEcHiH3uSgcHiEcHiEcHiH3uSj3uSj3uSj3uSj3uSj3uSgcHiH3uSgcHiEcHiEcHiEcHiEcHiEcHiEAyIIcHiEAyIIAyIIAyIIcHiEAyIL3uSgcHiEcHiEAyIL3uSj3uSgcHiEAyIIcHiH3uSj3uSj3uSj3uSgAyIIAyIIAAAAcHiEAyIL3uSi0ITmYAAAA+3RSTlMA6yr7BIHV8wL9Bo+l6b0cDJPhEL/dFPnx7e/1wefJLNkmTrcYiZUKhc1qfjDlFnB4GqlAi7mr17t2jdsIpyTPSB6vZPd0KLVMOONaVDpQIpFEbhIgSp9ol3yHDplcy3qhNN8uPgLFnaM2rTxYm8ezYoOx0cNWQmz1BNPzUvtm+WBGi2rxUN1U+dWlcCrZDF4ych529/U+/f2911xa9wavPky9venbapEqdEIIHPNYUocq906JegwCFiynQredQMs8Dpn7Ejjlk7MK61Ji7S56qWjt8+d+bqPvsTBOSGQ8oZvX6wYKm++f20y/8aeNDjYWz7Hn8cXXEMPJx5v4g7kAABPcSURBVHja3ZsFcBtZtoZ/WbLIFliyLLIsy5KZHVPMHGPMFCcOTphxJslMJjOzw7g0O7NMb98yMzM+ZmZmhuO4Xndb0r233V0VbyaVevuVSyXpq3v6gPt2dcdBEldFvNBiKYxXuCBQf8pGSWyn6sEospCxeSzmdsfGmo1kKUqLGRv1dSFJVx/ZrqRW2GzbwbHdZttYVW8hSQiKLMqxTlEfYH2pEow+OiWnazN2AXuJbjLTZbS5gApqBjBKdB6MZqoA4jQGIEwUAmOM4kAhxQDkEvWDEaNCwEJuOXOiHjDcZAFC5IVEA0XmVGaV9ivvL1D7EHBiV306WgONbRRspoGybQbyZ6UyqJVeFLxxUjCksl4JUwwbXG+XTV2qUpTQUaQ4sVy2P90d9NMZaHf0OC0CWlOwW6j34Ezb3ObJTZMtKI8/frLKK047i4g8+xYGNv+GtO57WI7knTneHWK/VXcB6/ZyPwn4y7dbZZFLGuRa5VZosh0o1zblgF/b+AHaYH7CoIxtYp42SJsJZBgkkYEJ0cjfSUp5YYZTimCGU7LYilFH089AP2v9SvW7o99R/SnoT05/2ncF03i2vCNmj5sgstNHjoa2tgYH+XaCw9pI3T1W5V1PNzVyaTVSjikdNocaWSjKAUcOpQKafN1WJHbfTK/q9iUjjFMP0ExmpOihcShkO6xAkGgknZAjGwqFDQDayZFAioZCKFjalL0hjjRtFiiEpgDYy2lmk1ndAQlXNe0yreSXzXLRsiNKknPt5GkhcigZiEm624xE1MRljcJVbJCoPVJbylWKvlHodMeyxPed6+g0DVY0O3eahCmwvcpDkfNTbHLcXmWd7+wOsWnfI2YPh/q1zQxRSNtMEx2GjpqZxZaobQ/15WmJvKxOoiloUkQU1zaniRb0ltCwptlHdBqaxImKtM0UUXaWdtp9ofZa3DseeOLp565de+7pJx6AyOseX0vy+OvAcd8ja2tPPfPs888/+8xTa2uP3MfMI2s3Hk1+vO/RG2uPsFBrNz4kffelf7/2r5L/0I21VMAHHl97FMCXpIN86h8APLr2eDKNJ9aekkOtyfylHPCptSeg8PTaM5B4UDYPQuKZtaeh8Nzas5D4dWURJJ5dew4K19aeh8Sv3Fhbu/GbkHh+7Zpg8EvXfvU3wAyLxpCjsQwe+MD7H5QSeP8H/kzJgGX9j2ufWlN405/+uZw1q/RvlZyVvP+EVSp158FrKSGtelDqDuuowCPcFP6YF390Hzj+4E3pYG9VT/ut733fjRvve+9bH8AdUtUaoBSB1ipO+D1ZmSmyPH6mWj1eMLyeVqQIZIEnK4AUlCmYTLr3Rj9r/UqF7iy7gJFK1h2uo8v2RhvrKAcdN9NSKTQgqr4JTQqPevFTMH50Wlt0+MkyrmncfqJ2TWO1EflNWiYaJgrXaJkpI5FRa40pQAq24IKb1S+BItko+EtEY6Y0uaIhhlPX+PWMcVXPWIr0TPigjhnIhGhajKklGSqT6AwrIvgQVOanw7S3tbhG05RRwYDHqzmgAF70t2mZXX6g1adlToWBNr+GyBs4AjSHM2t71CPPtMWAFpIwzyLJeZI4E+yDgr3IVpwylJ+ZmUt0DEkKm/kzuJL2IMmKY4douFM4pGOGCrt1zDSNaRt7I2VomyJagGha9mXK7Cq0eCHWE4+QjLF8GyD04Dxeawrb9AzRbj3joX1WbZO5lxpMUFFTdzFEy6il83bVPfIAXciudAGL1NTBi2xy7scGD9tyS5nZTYNIs8Q9F5mgXUwIa1Y9HYBrvr9OfZwuqsB4q41oU26DlNFM7Xv312+q50yk3Vir2YNusoxo981AO3V63bIXry2XBmiDSxB4KIuKoFAUFsdfPkhIQlPC7uIGgRRAg6uFzJgPgq1BKTHTMMatQbSFmeVd/JqxBmaKdiTXKGbXMjOTHn7NjiIwwiuc8UyCUTDBzIpQ65GHmJko4M1MSTjVHVo8xZubnv7UZn2pZAY8DdRe4D9wvuxSRp7nJtSYYtczj7dTA26LmI0ULOasDIicoxS2HJN4iAOUximoHOLIAWPIxhsbd6wsEsjipi0aMzMW0VgEU5M++SUlRBvmb7aEDJqwslRdvduLJsFk2IjO9XY6HJ29SjdUlebPJxLz+aQyJifxgFc5Nt4IZGSZLaHuxmMhIt+dTu5qHiTcVZWBTZO7gg3mclWT62N7Sq4wOYcXaeYC/OQywVHJT66KN1X85Ny8cVsE09/ks9iMlvb4WcAmRPOdnSu1Wt2T/T6An1wl2rInGyKRhsnsRsFkBObsrbamgwebbK12wSAnF9axfIMhf0yuWJxc7hwUZicA1eQClVXuvBNllnbgDicHU21B0EgSxmBBrUlIgApKyjIlykoKhFOrllKDg31uhmqZKWAbygLNcZ8QLAHg6oxEOl3zC/aSIDPGMkkEA7t3B4IuoMzIX0aBzsAkMBnoBDJJNJHdkNgd2YIRoulnoJk1AJY1q5R90ugOwLqj01H9KegjTlvjnIO9xFa46+zZXYW2ErsonP66jWegdX6noEr8+5Fkv78E/L5Th20NpVCoE3bLQivM1A8FayF/zu0CAtSGDXbx59xZYIGi2OCshZnQQ0Be9aobVrvKrDYCqAoW9iwZBsVoWQfkYmKniWhUzGDSdgkywwtHo2LWdksFtCu9TEOH5qHVnSwaIDpQ3M86yj+djLV1h7SmoM+rt9K8Kppb/FvRcOiu0TLvepee+d73NM0nP/PKrVuvfOaTm83HXpaP/vLHNKJ9XDYfh4b5iGw+omXe9tEPfvCjb9tsPowkH367aP7qr/8JUGq69RcQedu/fes7wHe+9Xd/AzXf/P6PfvKTH33/m9DgF//3f34RW8NIEkta5moVkDDctiEVnIHA7RkV4BR+ug+VJFGpNvf+w1XiuIo7J09+5mBsyYNIzfRwoXxhto4VDk/zsodOty5CYbE1lzKYqX4RHA9zadsg4WpyOJrcGO+GTazNTcsu1xS5XOPqaTdNQWK5CVAbh0sJ6diKaVqGxJRGNBdNuVzLtKIyJjk5OWs5pMnPmXwT0pjy85GmNN9PHKXQ586vc6Sw+TpHaVTXOZLp7iYZ8TpHEgOlpX7tuwIjYNS5K/B69e4KYjFSsGwyhw4xI0a7cIFFEzKwHayysQxY1rI5aGNZC5XabKxSne7od1QkqkxhKgP/z8g7fDhPW5iJzHnawmxmShR5eVrqsPSd4g+rzY6No9cc3oGfBbZFjKRgNA8LYphGrFCwnqBtvDGfQJqRCG+MVqSxGu/FtUQ/g+oJpDlhFlpAJ+RVCcA6QaommI3A9TCRsXobREyEylF5jQlqqPl0DbSwBjrtd75bsjt+nWcozi08Q2H7TnY2kfKq3i2zgezUq7hbMqPaLVk09W7Jo94t9w2QRHjf5t2yf6ihsLBhqF9jt1xyAa4ltlvylUYirFLt7uh2VHcKWyCa4wuHfTlRqDCdMtQNud1DdYYsiLSsuqHgphYhhSMRpFnlV0UNbqRxG6JcC+qAHTuAjdc6rgm+Id4M+ZgJi89QwvpGjLazAxIdO+VoYgZF5qL6eulFyUDMek/cYIjvUWWNI6tIQ6eEtrVQqjvZLRA5kuroEZPuFO4ZVfEBsg3E90NF71GLpT/W1U+W7Dkx5eoFmoXErOFIpAaMFdqTO48JI41gPreMJplpeQGGBIjIiBoDaguZ8Ywj0gu/pNAbwc1RLi+67tyJYzRwDDud85QAw2XICiRQWooEZTkmwNPVF6LFoa7FcKhvCCqOSZXSQNMINLDKP/eMnqPlPoXy7Gno7olTYJwkgZPMNJFnfmV/AR074nPD5IxzvbbU580crKPSwXw8XGbwMGNpxCoRKSZf2PmMlzKIKCCZHbhUTEbOjEeJGjrCpYNL6HAFOGMpxgUqgWFzNE8gkaidk9cohssgTr7LHVWnqWp3+2w7UVy/Uv0rBk9PdrnHYLEYPOVHe3AXGeszV0ckqs3n9whiH52MJuolEtFxOgrGXksp0pRSBdI45wErqyCX61uvtZlaZkFQThR+cu6sw3nHFKN6rmw0RRIAksZq5A3VA63JaFYbH62T8iZJI1qg15oTHN0PQiUgZODsEfruRJorxFdq2QvG0dFL0bwVk2klL3qSKsGzp8/ssBiNFoe5bwyvBfZih6PYrmWKSaJYyzhk49A3W4s2TRYLTWuZVY/d7lnVEJfoBeAFugQ1pvYL8l51od2kNhXUo0yAKtTlGz125Z3HyBrBEmbvxCLDlRJhVi4zDId+NPUAuHe3yTgF2g8fX8qsGI+CcXAJpTThjZ0Yr8hcOk67mMk3YM6DFDXETLAdIwUos5RtGAMz1eUoOoNwcpOKmpkxO9F/JL3mci4zh/uwN3nYndWHTjYwE1/AVC1kXrJR8FwOM51ZaDjZ65xBptK2vczszkRuXZBsRT2yCfVzHa1FIUlYZoxEZChipu4sApQmOMJMxXWrjZnAJDNjJ2uIYSxlZuQcWjllAqO5HiNjdUt9p9sNfrqMu8nZnA5tYadmT5G2ImxraRrSNjDVBtvcmgbIOxLZo22A/dWkY46RtqlZ0I5mmgk2ujWzNrfGdCrduZXu3Hu8xGEs8DJT0Mzf7TaTeBvMKRJ6RmmAO3hKffeiaRixHiNnjgs9KOD6VmAkDi/uFt2Uu03bEJGOO0B6boFIx+0k0nNEeq6qVv7rzNzcXNnpG/1oehnoZa1XqV53dDv6GpOgc3qKDizqmbnqPToGMcd1qLEXHXcQcNBwEyL15RfGEsoGFzwkiJXR9LG3GfYLJ20lNysCY3CVi+t7CQzfi6zc9kEw9rdL4acOBGxATft2cDQuI7twb5eXUFO4FzxN8/vIDoDyWpZVIz3TboVsPJUQIVrZ2LIaoTYvQMGErRItOB2FBh2DltFRy2CHegR7jodpRyKxg8LH99h5k0ueqQm8+CImpjzk5A1lAb2NRmNjLzBFgqlEASkUIFNtKInKGMuYKTPyxrOAyIaoxoJHyK0c2RvmKMpzeTNDsa4BWQx0xWiGNzX+ZhxyEDkOodlfA55BqkDHnj0dqKBBCFjPUM4sMJtDZ6xQqUYaOHp0gBoVITJU4vGUxLAV/n7953XMW95y/88BeMe7f+t3IfLk+vr97/n9d77xsfXfhsj96+vrTz4mvTz2exB543qSN75DFH+4nuJ3wPP5T6SXPPZuXvzXf96fXvLke3iz/pZ1hpQ847/lpJjiS/7hj9+5/u2kkAIw8fo3SMVLpUr82v1Prv8yM294veTeKQd6M1S8+RfejB8/tn7/JzTE69/ww/Vv/8vnocBHk3/+Y/2fsTWWKEPH2HYGFwHYhxeqIBIu7So/05MdyL8QgkhoFqbi/MUa5BZBxJKQYwE1AbsoTtAsFB7qBI810xFNPcUd5oW3uzV9AhSf4Q1xEUzli2A4w02L6UVdQb7k0uvZ1AKJ2cRs6U5ionc7YA8ngCgZQmFaYmZ7r+SyF1ETOQQVh4KHcL0VrZkaond7KWUetkKBjyb/5FMNtoq96oXGpupQfAg8ebUNLTbaILICxsEgcfTz7SGJ9DP8En6g8pfp5/61YIxufLnxUu4GI75h5IW2xo5BMBpTh6DQ5ZodATD2EPnisjBeHnFQARhVRA2mq5JZnjQQ7eLLtxEdyrhKjtImIlsMHC1Eo9tM8bZjm/7eo4EkOtuv7yVqsgvmJVKoP0PODgjUBJVF3gN1dqg4eHHAV2eq6dj65NqaIqSaeayuocV/tbNuvt6d4+gFo96QMxY1YYN9FWAIF9/FI7xJjZ5Iqi0ERrULIEqavWF+csNJI7FMRn5yddyftp9w8JPrTAlzU8cJYXJXge1eAMU5wO5Bvny/CYM+L/IMvagP1guTiwKVjbh0HrhQDJ7mk5DJGrTuEP5wPfWvDaW+ivw+EwRihuIVVxtFPBVQU080Wn18mwn3Fhf5tUWUiDRFLKRjJoM2HTNqoy0bMZp+BiLRgJ5BTDI/MxDFdE0gqmcoFNMztuCkjiHbqK7x6EfbcgY6WfvJhXuM11zs1RblV66UezVFG9DGlCgk1V2qNi2KALLIpFpCpDxiMRKp4rk74IsBXT5o7P/xeaCnCRrk1AIzJVrmSoliNehpBeJFWqbLAVCVlrGShBVqKgHYAbf89nYf3LRQmhbcRS5f1jMWi+KrH4IaouR/1q9Qm8jGr27FZtVJcR3lClKaaZXqjDCjhkXbipjWFKzSe8FwusrqYdFIIq1EQwr59bATaZkoAG1jhYO0DUCaBjJuXdO1hWi6ppoZVaXDigJYd26L/gKLpaAfm0g4Lw4nEsMXnQm1cZZZIWEtc6pDXbRfXVbURVXAguGM5OlZVKC++zIF2zYOaBFNyIvxwDFM2jeZ09NAxcCpUPWcOtpDZwC8uCPkLFVnMH0a0M4662Jn87RXq9LWhYcXT4c0u6PPD24l+QFum1tptMwrr+iZ735X23z6c8DnPq1lXv0C8IVXNaN9GfiyRrS337r1ja9+9Ru3br1dbT778kbOL38War74FVl85YvQ4Gtf//rXsBUymn0OCV9zDCJdFkpi6RJNNqXJ1ngQPDpKEj7RhGdN2/us1r4udIVFY4OjI3ruXJRANrXB/o6LFzs2mzCC9uQaVTTfrPWKfBzqogOqrFlu2bdbKWLNvpDRGPA1ZOA1YmREzzideiY/f2tmxJmfHwrl5ztH9M0dH4dlrV/pa0h3OTToLfPmEeV5y3rVpowMTiKngcrUxmsgBYNXbfKcFHe54uTMUx+ciFyAi4jK9Y1uNP0M9LPWr1SnO1vg/wDZSSIGDqRwtgAAAABJRU5ErkJggg=='); + display: inline-block; + width: 18px; + height: 18px; + background-size: auto; + background-repeat: no-repeat; + margin-right: .5em; + filter: invert(39%) sepia(21%) saturate(200%) saturate(109.5%) hue-rotate(174deg) brightness(94%) contrast(86%); +} + +.blue { + filter: invert(39%) sepia(57%) saturate(200%) saturate(200%) saturate(200%) saturate(200%) saturate(200%) saturate(147.75%) hue-rotate(202deg) brightness(97%) contrast(96%); +} + +.like { + background-position: 0px -132px; +} + +.comm { + background-position: 0px -113px; +} + +.createpost { + position: relative; + background-color: white; + width: 450px; + padding: 20px; + border-radius: .5em; + box-shadow: 0 2px 4px rgba(0, 0, 0, .1), 0 8px 16px rgba(0, 0, 0, .1); +} + +.createpost .postheader { + margin-top: 20px; +} + +.createpost textarea { + border: none; + resize: none; + outline: none; + font-family: sfpro; + font-size: 24px; + margin-top: 10px; + width: 100%; + height: 120px; + margin-bottom: 20px; +} + +.createpost>span { + margin-top: -10px; +} + +.primary { + margin: 0; + width: calc(100% - 20px); + font-family: sfprobold; + height: 15px; +} + +.close { + top: 1em; + right: 1em; +} + +.comment { + display: flex; + flex-direction: row; + margin-bottom: 10px; +} + +.comment p, .post p { + word-break: break-all; + white-space: normal; +} + +.comment>span { + display: flex; + flex-direction: column; + margin-left: 10px; + background-color: #f0f2f5; + border-radius: 10px; + padding: 10px; + padding-right: 10px; +} + +.larger { + font-size: 18px; +} + +.newcomment { + display: flex; + flex-direction: row; +} + +#comments input { + all: unset; + padding: 10px; + border-radius: 10px; + width: calc(100% - 20px); + background-color: #f0f2f5; + font-family: sfpro; +} \ No newline at end of file diff --git a/public/css/login.css b/public/css/login.css new file mode 100644 index 0000000..7e5cde7 --- /dev/null +++ b/public/css/login.css @@ -0,0 +1,47 @@ +.login { + background-color: #f0f2f5; + display: flex; + justify-content: center; + align-content: center; + flex-direction: row; + padding: 8em 0em; +} + +.prompt { + display: flex; + position: relative; + flex-direction: column; + background-color: white; + box-shadow: 0 2px 4px rgba(0, 0, 0, .1), 0 8px 16px rgba(0, 0, 0, .1); + border-radius: 8px; + width: 396px; + padding: 10px +} + +.show { + display: flex; + flex-direction: column; + justify-content: center; +} + +.login-button { + margin-bottom: 10px; + font-size: 20px; +} + +.newacc { + margin: 10px 70px; + margin-bottom: 20px; +} + +.signacc { + margin: 10px 70px; + margin-bottom: 0; +} + +@media (max-aspect-ratio: 2/3) { + .login { + flex-direction: column; + align-items: center; + } +} \ No newline at end of file diff --git a/public/css/main.css b/public/css/main.css new file mode 100644 index 0000000..c1b4fa2 --- /dev/null +++ b/public/css/main.css @@ -0,0 +1,307 @@ +body { + background-color: white; + width: 100vw; + height: 100vh; + margin: 0; + padding: 0; + display: flex; + flex-direction: column; +} + +@font-face { + font-family: facebook; + src: url("../fonts/facebook.otf") format("opentype"); +} + +@font-face { + font-family: sfpro; + src: url("../fonts/sfpro.otf") format("opentype"); +} + +@font-face { + font-family: sfprobold; + src: url("../fonts/sfprobold.otf") format("opentype"); +} + +.logo { + color: #1778f2; + font-size: 3.5em; + font-family: facebook; +} + +.text { + font-family: sfpro; + font-size: 28px; + font-weight: normal; + line-height: 32px; + width: 500px; +} + +.btext { + font-family: sfpro; + color: #1778f2 +} + +.error { + font-family: sfpro; + color: #f02849; + padding-top: 10px; + margin-bottom: -10px; + font-size: 15px; +} + +.gtext { + font-family: sfpro; + color: #606770 +} + +.label { + font-family: sfpro; + color: #606770; + font-size: 15px; + padding-top: 10px; + padding-left: 10px; +} + +.stext { + font-family: sfpro; + font-size: 10px; +} + +.mtext { + font-family: sfpro; + font-size: 15px; +} + +.ltext { + font-family: sfpro; + font-size: 22px; +} + +.ctext { + display: block; + font-family: sfpro; + text-align: center; +} + +a { + color: inherit; + text-decoration: none; + cursor: pointer; +} + +p { + padding: 0; + margin: 0; +} + +span { + padding: 0; + margin: 0; +} + +footer { + bottom: 0; + height: 400px; + background-color: white; +} + +input { + flex: 1; + font-family: sfpro; + background-color: white; + padding: 10px; + margin: 10px; + margin-bottom: 0; + border-radius: 5px; + border: 1px solid #dddfe2; + color: #1d2129; + font-size: 18px; +} + +.radiomenu { + display: flex; + flex-wrap: wrap; +} + +.radiomenu span { + display: inline-block; + position: relative; + font-family: sfpro; + background-color: white; + margin: 10px; + margin-bottom: 0; + border-radius: 5px; + border: 1px solid #dddfe2; + color: #1d2129; + font-size: 15px; + flex: 1 0 auto; +} + +.radiomenu span label { + padding: 10px; + display: block; + box-sizing: border-box; + width: auto; + color: #1d2129; +} + +[type="radio"] { + height: 40px; + margin: 0; + position: absolute; + right: 10px; + top: 0; + text-align: left; +} + +select { + all: unset; + flex: 1; + font-family: sfpro; + background-color: white; + padding: 10px; + margin: 10px; + margin-bottom: 0; + border-radius: 5px; + border: 1px solid #dddfe2; + color: #1d2129; + font-size: 15px; + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYAgMAAACdGdVrAAAADFBMVEVMaXEFBQUFBQUFBQXG+MOgAAAAA3RSTlMAn3BcqiM3AAAAOUlEQVQIW53BsQ2AMAwAMJelV6C80qPYw4k9JmskbqA2px5uNIlcoxF7FmbFxuhckA2iwNzgev3wAR4FDUQbc/qhAAAAAElFTkSuQmCC"); + background-position: right 10px center; + background-repeat: no-repeat; + background-size: 15px; +} + +input:focus { + border: 1px solid #1778f2; +} + +.primary { + all: unset; + font-family: sfpro; + background-color: #1778f2; + color: white; + padding: 10px; + margin: 20px; + border-radius: 5px; + padding-bottom: 15px; + text-align: center; + cursor: pointer; +} + +.success { + all: unset; + font-family: sfpro; + background-color: #42b72a; + color: white; + padding: 10px; + margin-left: 10px; + margin-right: 10px; + border-radius: 5px; + text-align: center; + cursor: pointer; +} + +.bold { + font-family: sfprobold; +} + +.line { + width: calc(100% - 40px); + margin-left: 20px; + margin-right: 20px; + border-bottom: 1px solid #dadde1; + margin-bottom: 10px; + margin-top: 10px; +} + +.fullline { + width: calc(100%); + border-bottom: 1px solid #dadde1; + margin-bottom: 10px; + margin-top: 10px; +} + +footer { + text-align: center; + font-family: sfpro; + padding-top: 30px; + padding-bottom: 30px; + font-size: 13px; + color: #737373; +} + +#popup { + position: absolute; + width: 100vw; + height: 100vh; + background-color: rgba(255, 255, 255, .8); + margin: 0; + padding: 0; + top: 0; + display: flex; + justify-content: center; + align-items: center; +} + +.row { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; +} + +.row input { + width: 50% +} + +.close { + position: absolute; + z-index: 2; + width: 20px; + height: 20px; + right: 12px; + top: 12px; + cursor: pointer; + background-size: 20px; + background-position: right; + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYAgMAAACdGdVrAAAADFBMVEVgZ3FHcExgZ3FgZ3Fd28LEAAAAA3RSTlOfAHBcPEovAAAASklEQVQIW2MIBQMG7FRmaGgmUG5PaKgdkNovGvIPSPkfDf4IpII/+h8FUiF/7EVB2u3/gE3x/4hMQQShSqAaoNqhhkGNhlqE2y0A1E85Y0JErBoAAAAASUVORK5CYII='); +} + +.hidden { + visibility: hidden; + pointer-events: none; + display: none !important; +} + +.pfp, .pfp img { + display: block; + width: 2.5em; + height: 2.5em; + border-radius: 3em; + background-color: #e4e6e8; + flex-shrink: 0; +} + +.nb { + margin-bottom: 0; +} + +form { + all: unset; + border-radius: 10px; + margin-left: 10px; + width: 100%; +} + +#load { + width: 100%; + display: flex; + justify-content: center; + padding-bottom: 20px; +} + +#load a:hover { + border-bottom: #606770 1px solid; +} \ No newline at end of file diff --git a/public/css/people.css b/public/css/people.css new file mode 100644 index 0000000..b8cf025 --- /dev/null +++ b/public/css/people.css @@ -0,0 +1,44 @@ +body { + background-color: #f0f2f5; +} + +#users { + display: flex; + flex-direction: column; + align-items: center; +} + +.person { + width: 30em; + height: fit-content; + background-color: white; + border-radius: 10px; + box-shadow: 0 2px 4px rgba(0, 0, 0, .05); + margin-bottom: 1.5em; + display: flex; + flex-direction: row; +} + +.profile, .profile img { + border-radius: 10px 0px 0px 10px; + width: 10em; + height: 10em; + padding: 0; + display: block; + background-color: #e4e6e8; + flex-shrink: 0; +} + +.info { + margin: 20px; + display: flex; + flex-direction: column; +} + +.info span { + width: 280px; + margin-bottom: 5px; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} \ No newline at end of file diff --git a/public/css/profile.css b/public/css/profile.css new file mode 100644 index 0000000..4c5ae10 --- /dev/null +++ b/public/css/profile.css @@ -0,0 +1,121 @@ +body { + background-color: #f0f2f5; +} + +.spacer { + margin-bottom: 3.5em; +} + +#top { + background-color: white; + display: flex; + flex-direction: column; + align-items: center; + width: 100%; + box-shadow: 0 2px 4px rgba(0, 0, 0, .05); +} + +#banner { + background-image: linear-gradient(#949494, white, white); + height: 30em; + width: 100%; + display: flex; + justify-content: center; +} + +#banner div, #banner img { + width: 80em; + height: inherit; + background-color: #e4e6e8; + border-radius: 0px 0px 20px 20px; +} + +#info { + width: 80em; + display: flex; + flex-direction: row; +} + +.face { + background-color: #e4e6e8; + height: 12em; + width: 12em; + border-radius: 7em; + border: solid 5px white; + margin-top: -2em; + margin-left: 2em; + margin-right: 2em; +} + +.infodata { + margin-top: 2em; + display: flex; + flex-direction: column; +} + +.infodata span { + margin-bottom: .5em; +} + +.profilebuttons { + width: 80em; + height: 3em; + display: flex; + align-items: center; +} + +.profilebuttons button { + all: unset; + font-family: sfprobold; + padding: 0px 50px; + height: 100%; + display: flex; + align-items: center; + justify-content: center; + color: #606770; + cursor: pointer; +} + +.profilebuttons button:hover { + background-color: #dddfe2; +} + +.selected { + color: #1778f2 !important; + border-bottom: 3px solid #1778f2 !important; +} + +#about { + margin-top: 2em; + align-self: center; + padding: 0; + display: flex; + flex-direction: row; +} + +#posts { + margin-top: 2em; +} + +#about .ltext { + border-right: 2px solid #dadde1; + padding: 10px; + padding-right: 3em; +} + +#about .data { + display: flex; + flex-direction: column; + padding: 10px; + padding-left: 20px; + padding-top: 15px; +} + +#about .data span { + margin-bottom: 10px; + width: 28em; + margin-bottom: 5px; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} \ No newline at end of file diff --git a/public/fonts/facebook.otf b/public/fonts/facebook.otf new file mode 100755 index 0000000..97d5c6f Binary files /dev/null and b/public/fonts/facebook.otf differ diff --git a/public/fonts/sfpro.otf b/public/fonts/sfpro.otf new file mode 100644 index 0000000..09aaca9 Binary files /dev/null and b/public/fonts/sfpro.otf differ diff --git a/public/fonts/sfprobold.otf b/public/fonts/sfprobold.otf new file mode 100644 index 0000000..025b25c Binary files /dev/null and b/public/fonts/sfprobold.otf differ diff --git a/public/home.html b/public/home.html new file mode 100644 index 0000000..865e53a --- /dev/null +++ b/public/home.html @@ -0,0 +1,17 @@ + + + + + + + + XSSBook - Home + + + + + + + + + \ No newline at end of file diff --git a/public/js/api.js b/public/js/api.js new file mode 100644 index 0000000..07769f6 --- /dev/null +++ b/public/js/api.js @@ -0,0 +1,63 @@ +const endpoint = '/api' + +const request = async (url, body, method) => { + if (method === undefined) method = 'POST' + const response = await fetch(endpoint + url, { + method, + body: JSON.stringify(body), + headers: { + 'Content-Type': 'application/json' + } + }); + if (response.status == 401) { + location.href = 'login' + } + const contentType = response.headers.get("content-type"); + if (contentType && contentType.indexOf("application/json") !== -1) { + const json = await response.json() + return { status: response.status, msg: json.msg, json } + } else { + const msg = await response.text(); + return { status: response.status, msg } + } +} + +const login = async (email, password) => { + return await request('/auth/login', {email, password}) +} + +const register = async (firstname, lastname, email, password, gender, day, month, year) => { + return await request('/auth/register', {firstname, lastname, email, password, gender, day, month, year}) +} + +const loadpostspage = async (page) => { + return await request('/posts/page', {page}) +} + +const loadusersposts = async (user_id) => { + return await request('/posts/user', {user_id}) +} + +const loadusers = async (ids) => { + return await request('/users/load', {ids}) +} + +const loaduserspage = async (page) => { + return await request('/users/page', {page}) +} + +const loadself = async () => { + return await request("/users/self", {}) +} + +const postcomment = async (post_id, content) => { + return await request('/posts/comment', {post_id, content}, 'PATCH') +} + +const postlike = async (post_id, state) => { + return await request('/posts/like', {post_id, state}, 'PATCH') +} + +const createpost = async (content) => { + return await request('/posts/create', {content}) +} \ No newline at end of file diff --git a/public/js/header.js b/public/js/header.js new file mode 100644 index 0000000..8fe03e5 --- /dev/null +++ b/public/js/header.js @@ -0,0 +1,25 @@ +function header(home, people) { + const html = ` + +
+ ` + + add(html, 'header') +} \ No newline at end of file diff --git a/public/js/home.js b/public/js/home.js new file mode 100644 index 0000000..fd40ebf --- /dev/null +++ b/public/js/home.js @@ -0,0 +1,233 @@ +const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; + +function parseDate(date) { + return months[date.getUTCMonth()] + ' ' + date.getUTCDate() + ', ' + date.getUTCFullYear() + ' ' + date.toLocaleTimeString(); +} + +function parseComment(comment) { + const author = data.users[comment[0]] + if (author === undefined) { + author = {} + } + const html = ` +
+ + + + + ${author.firstname + ' ' + author.lastname} +

${comment[1]}

+
+
+ ` + return html +} + +function parsePost(post) { + console.log(post.likes) + const author = data.users[post.user_id] + if (author === undefined) { + author = {} + } + const html = ` +
+
+ + + +
+ ${author.firstname + ' ' + author.lastname} + ${parseDate(new Date(post.date))} +
+
+

+ ${post.content.replace(/\n/g,'
')} +

+ + ${Object.keys(post.likes).map(k => post.likes[k]).filter(v => v !== false).length} Likes + +
+
+ + + Like + + + + Comment + +
+
+
+ ${post.comments.map(parseComment).join('')} +
+ + + +
+ +
+
+
+
+ ` + + return html +} + +function getPost(post_id) { + for (let i = 0; i < data.posts.length; i++) { + if (data.posts[i].post_id === post_id) { + return i + } + } + return -1 +} + +async function like(span) { + const id = parseInt(span.parentElement.parentElement.getAttribute('postid')) + const post = data.posts[getPost(id)] + const index = post.likes.indexOf(data.user.user_id) + const current = index !== -1 + const response = await postlike(id, !current) + if (response.status != 200) return; + if (current) { + post.likes.splice(index, 1) + } else { + post.likes.push(data.user.user_id) + } + render() +} + +async function comment(event) { + event.preventDefault(); + const text = event.target.elements.text.value.trim(); + if (text.length < 1) return; + const id = parseInt(event.target.parentElement.parentElement.parentElement.getAttribute('postid')) + var index = getPost(id); + if (index === -1) return; + const response = await postcomment(id, text) + if (response.status != 200) return; + event.target.elements.text.value = ''; + data.posts[index].comments.push([data.user.user_id, text]) + render() +} + +async function post() { + const text = document.getElementById("text").value.trim() + const error = document.getElementsByClassName('error')[0] + if (text.length < 1) return; + const response = await createpost(text); + if (response.status != 201) { + error.innerHTML = response.msg + return; + } + error.innerHTML = ''; + data.posts.unshift({ + post_id: response.msg, + user_id: data.user.user_id, + date: Date.now(), + content: text, + likes: [], + comments: [] + }) + render() +} + +function render() { + const html = ` +
+
+ + + + +
+ ${data.posts.map(p => parsePost(p)).join('')} +
+ ` + + add(html, 'posts') + + const popup = ` + + ` + + add(popup, 'popup') + + const load = ` +
+ Load more posts +
+ ` + + if (page !== -1) { + add(load, 'load') + } else { + remove('load') + } +} + +var page = 0 +const data = { + user: {}, + users: {}, + posts: [] +} + +async function load() { + const posts = (await loadpostspage(page)).json + if (posts.length === 0) { + page = -1 + } else { + page++ + } + data.posts.push(... posts) + const batch = [] + for (const post of posts) { + for(const comment of post.comments) { + if (data.users[comment[0]] !== undefined) continue + if (batch.includes(comment[0])) continue + batch.push(comment[0]) + } + if (data.users[post.user_id] !== undefined) continue + if (batch.includes(post.user_id)) continue + batch.push(post.user_id) + } + const users = (await loadusers(batch)).json + for (const id in users) { + data.users[id] = users[id] + } + render() +} + + +async function init() { + header(true, false) + data.user = (await loadself()).json + data.users[data.user.user_id] = data.user + load() +} \ No newline at end of file diff --git a/public/js/login.js b/public/js/login.js new file mode 100644 index 0000000..f65808b --- /dev/null +++ b/public/js/login.js @@ -0,0 +1,29 @@ +async function onlogin() { + const email = document.getElementById('email').value + const password = document.getElementById('pass').value + const response = await login(email, password) + if (response.status !== 200) { + const error = document.getElementsByClassName('error')[0] + error.innerHTML = response.msg + } else { + location.href = '/home' + } +} + +async function onregister() { + const first = document.getElementById('firstname').value + const last = document.getElementById('lastname').value + const email = document.getElementById('newemail').value + const pass = document.getElementById('newpass').value + const month = document.getElementById('month').value + const day = document.getElementById('day').value + const year = document.getElementById('year').value + const gender = document.querySelector('input[name="gender"]:checked').value + const response = await register(first, last, email, pass, gender, parseInt(day), parseInt(month), parseInt(year)) + if (response.status !== 200) { + const error = document.getElementsByClassName('error')[1] + error.innerHTML = response.msg + } else { + location.href = '/home' + } +} \ No newline at end of file diff --git a/public/js/main.js b/public/js/main.js new file mode 100644 index 0000000..0003c0d --- /dev/null +++ b/public/js/main.js @@ -0,0 +1,22 @@ +var range; + +function add(html, id) { + const old = document.getElementById(id) + if (old !== null) { + old.remove() + } + if (range === undefined) { + var range = document.createRange() + range.setStart(document.body, 0) + } + document.body.appendChild( + range.createContextualFragment(html) + ) +} + +function remove(id) { + const old = document.getElementById(id) + if (old !== null) { + old.remove() + } +} \ No newline at end of file diff --git a/public/js/people.js b/public/js/people.js new file mode 100644 index 0000000..ddd1875 --- /dev/null +++ b/public/js/people.js @@ -0,0 +1,65 @@ +const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; + +function parseDate(date) { + return months[date.getUTCMonth()] + ' ' + date.getUTCDate() + ', ' + date.getUTCFullYear() + ' ' + date.toLocaleTimeString(); +} + +function parseUser(user) { + const html = ` + +
+ +
+
+ ${user.firstname + ' ' + user.lastname} + Joined ${parseDate(new Date(user.date))} + Gender: ${user.gender} + Birthday: ${months[user.month] + ' ' + user.day + ', ' + user.year} + User ID: ${user.user_id} +
+
+ ` + return html +} + +function render() { + const html = ` +
+ ${data.users.map(u => parseUser(u)).join('')} +
+ ` + + add(html, 'users') + + const load = ` +
+ Load more users +
+ ` + + if (page !== -1) { + add(load, 'load') + } else { + remove('load') + } +} + +var page = 0 +var data = { + users: [] +} + +async function load() { + const users = (await loaduserspage(page)).json + if (users.length === 0) { + page = -1 + } else { + page++ + } + data.users.push(... users) + render() +} + +header(false, true) +load() \ No newline at end of file diff --git a/public/js/profile.js b/public/js/profile.js new file mode 100644 index 0000000..79dbe2f --- /dev/null +++ b/public/js/profile.js @@ -0,0 +1,88 @@ +function render() { + const html = ` +
+ +
+
+ +
+
+ ${data.user.firstname + ' ' + data.user.lastname} + Joined ${parseDate(new Date(data.user.date))} +
+
+
+
+ + +
+
+ ` + + add(html, 'top') + + const postsh = ` +
+ ${data.posts.map(p => parsePost(p)).join('')} +
+ ` + + add(postsh, 'posts') + + const about = ` +
+ About +
+ Name: ${data.user.firstname + ' ' + data.user.lastname} + Email: ${data.user.email} + Gender: ${data.user.gender} + Birthday: ${months[data.user.month] + ' ' + data.user.day + ', ' + data.user.year} + User ID: ${data.user.user_id} +
+
+ ` + + add(about, 'about') +} + +var posts = true + +async function load() { + header(false, false) + + var params = {}; + for (const [key, value] of new URLSearchParams(location.search)) { + params[key] = value + } + + const id = params.id !== undefined && !isNaN(params.id) ? parseInt(params.id) : (await loadself()).json.user_id + const posts = (await loadusersposts(id)).json + data.posts.push(... posts) + const batch = [id] + for (const post of posts) { + for(const comment of post.comments) { + if (data.users[comment[0]] !== undefined) continue + if (batch.includes(comment[0])) continue + batch.push(comment[0]) + } + if (data.users[post.user_id] !== undefined) continue + if (batch.includes(post.user_id)) continue + batch.push(post.user_id) + } + const users = (await loadusers(batch)).json + for (const user of users) { + data.users[user.user_id] = user + } + data.user = data.users[id] + render() +} + +load() \ No newline at end of file diff --git a/public/login.html b/public/login.html new file mode 100644 index 0000000..97398f9 --- /dev/null +++ b/public/login.html @@ -0,0 +1,170 @@ + + + + + + + + + XSSBook - Login + + +
+
+ +

Connect with javascript and the world around you on XSSBook.

+
+
+ + + + + Forgot Password? +
+ +
+ +
+ + + \ No newline at end of file diff --git a/public/people.html b/public/people.html new file mode 100644 index 0000000..399751a --- /dev/null +++ b/public/people.html @@ -0,0 +1,15 @@ + + + + + + + + XSSBook - People + + + + + + + \ No newline at end of file diff --git a/public/profile.html b/public/profile.html new file mode 100644 index 0000000..d17ab09 --- /dev/null +++ b/public/profile.html @@ -0,0 +1,17 @@ + + + + + + + + + XSSBook - Profile + + + + + + + + \ No newline at end of file -- cgit v1.2.3-freya