From 7abf25345f9fb25f4227cb44000fae34b159ac1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Wo=C5=BAniak?= Date: Wed, 6 Jul 2022 15:33:14 +0200 Subject: [PATCH] Add register simple user and sessions --- Cargo.lock | 765 ++++++------------ Cargo.toml | 26 +- assets/templates/account.html | 45 +- assets/templates/base.html | 30 + assets/templates/index.html | 66 +- client/dist/app.js | 338 ++++---- client/dist/app.js.map | 2 +- client/src/app.js | 36 +- client/src/form-navigation.js | 2 +- client/src/{ => nav}/ow-nav.js | 0 client/src/{ => nav}/ow-path.js | 0 client/src/ow-account.js | 86 +- client/src/register-form.js | 36 +- .../src/register-form/register-basic-form.js | 2 +- .../register-form/register-item-form-row.js | 4 +- client/src/register-form/register-oauth2.js | 101 --- .../src/register-form/register-submit-form.js | 5 + .../src/register-form/register-user-form.js | 127 +++ client/src/shared.js | 7 +- migrations/20220706095417_add_facebook_id.sql | 1 + .../20220706130049_add_account_type.sql | 8 + src/main.rs | 20 +- src/model/db.rs | 9 + src/model/view.rs | 35 + src/routes/mod.rs | 2 + src/routes/unrestricted.rs | 220 ++++- src/utils.rs | 52 ++ 27 files changed, 1113 insertions(+), 912 deletions(-) create mode 100644 assets/templates/base.html rename client/src/{ => nav}/ow-nav.js (100%) rename client/src/{ => nav}/ow-path.js (100%) delete mode 100644 client/src/register-form/register-oauth2.js create mode 100644 client/src/register-form/register-user-form.js create mode 100644 migrations/20220706095417_add_facebook_id.sql create mode 100644 migrations/20220706130049_add_account_type.sql create mode 100644 src/utils.rs diff --git a/Cargo.lock b/Cargo.lock index 7b9fa7a..0435e09 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,29 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "actix" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3720d0064a0ce5c0de7bd93bdb0a6caebab2a9b5668746145d7b3b0c5da02914" +dependencies = [ + "actix-rt", + "bitflags", + "bytes", + "crossbeam-channel", + "futures-core", + "futures-sink", + "futures-task", + "futures-util", + "log", + "once_cell", + "parking_lot 0.11.2", + "pin-project-lite", + "smallvec", + "tokio", + "tokio-util 0.6.10", +] + [[package]] name = "actix" version = "0.13.0" @@ -23,33 +46,7 @@ dependencies = [ "pin-project-lite", "smallvec", "tokio", - "tokio-util", -] - -[[package]] -name = "actix-4-jwt-auth" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bf396fc31a619a76b0085283d6da671f41855eed5705cd5069152640052e438" -dependencies = [ - "actix-rt", - "actix-service", - "actix-web", - "biscuit", - "bytes", - "derive_more", - "env_logger", - "futures", - "futures-core", - "futures-util", - "log", - "reqwest", - "sanitize-filename", - "serde", - "serde_derive", - "serde_json", - "thiserror", - "tokio", + "tokio-util 0.7.3", ] [[package]] @@ -66,7 +63,7 @@ dependencies = [ "memchr", "pin-project-lite", "tokio", - "tokio-util", + "tokio-util 0.7.3", ] [[package]] @@ -144,6 +141,21 @@ dependencies = [ "zstd", ] +[[package]] +name = "actix-identity" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "171fe3ed055b2dd50c61967911d253d47e76e1d4308acfbf99fc7affe5ec42aa" +dependencies = [ + "actix-service", + "actix-utils", + "actix-web", + "futures-util", + "serde", + "serde_json", + "time 0.3.11", +] + [[package]] name = "actix-macros" version = "0.2.3" @@ -154,6 +166,27 @@ dependencies = [ "syn", ] +[[package]] +name = "actix-redis" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dde9fa8bde15d084d459eb59f766c08d00a6f550e7054187878fc9cbaa19115" +dependencies = [ + "actix 0.12.0", + "actix-rt", + "actix-service", + "actix-tls", + "actix-web", + "backoff", + "derive_more", + "futures-core", + "log", + "redis-async", + "time 0.3.11", + "tokio", + "tokio-util 0.6.10", +] + [[package]] name = "actix-router" version = "0.5.0" @@ -208,6 +241,22 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "actix-tls" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fde0cf292f7cdc7f070803cb9a0d45c018441321a78b1042ffbbb81ec333297" +dependencies = [ + "actix-codec", + "actix-rt", + "actix-service", + "actix-utils", + "futures-core", + "log", + "pin-project-lite", + "tokio-util 0.7.3", +] + [[package]] name = "actix-utils" version = "3.0.0" @@ -287,6 +336,41 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "aead" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" +dependencies = [ + "generic-array", +] + +[[package]] +name = "aes" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", + "opaque-debug", +] + +[[package]] +name = "aes-gcm" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df5f85a83a7d8b0442b6aa7b504b8212c1733da07b98aae43d4bc21b2cb3cdf6" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + [[package]] name = "ahash" version = "0.7.6" @@ -331,6 +415,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "argon2" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db4ce4441f99dbd377ca8a8f57b698c44d0d6e712d8329b5040da5a64aa1ce73" +dependencies = [ + "base64ct", + "blake2", + "password-hash", +] + [[package]] name = "askama" version = "0.11.1" @@ -388,23 +483,23 @@ dependencies = [ "num-traits", ] -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - [[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backoff" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1" +dependencies = [ + "getrandom", + "instant", + "rand", +] + [[package]] name = "base64" version = "0.13.0" @@ -412,19 +507,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" [[package]] -name = "biscuit" -version = "0.6.0-beta1" +name = "base64ct" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "058e3d6e7efa7593646c612165afef16974b5c31e1e92440fa6ddf28412bb627" -dependencies = [ - "chrono", - "data-encoding", - "num", - "once_cell", - "ring", - "serde", - "serde_json", -] +checksum = "3bdca834647821e0b13d9539a8634eb62d3501b6b6c2cec1722786ee6671b851" [[package]] name = "bitflags" @@ -432,6 +518,15 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "blake2" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9cf849ee05b2ee5fba5e36f97ff8ec2533916700fc0758d40d92136a42f3388" +dependencies = [ + "digest", +] + [[package]] name = "block-buffer" version = "0.10.2" @@ -518,6 +613,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "cipher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array", +] + [[package]] name = "convert_case" version = "0.4.0" @@ -530,27 +634,18 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94d4706de1b0fa5b132270cddffa8585166037822e260a944fe161acd137ca05" dependencies = [ + "aes-gcm", + "base64", + "hkdf", + "hmac", "percent-encoding", + "rand", + "sha2", + "subtle", "time 0.3.11", "version_check", ] -[[package]] -name = "core-foundation" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" - [[package]] name = "cpufeatures" version = "0.2.2" @@ -625,10 +720,13 @@ dependencies = [ ] [[package]] -name = "data-encoding" -version = "2.3.2" +name = "ctr" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57" +checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" +dependencies = [ + "cipher", +] [[package]] name = "derive_more" @@ -695,34 +793,12 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "env_logger" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" -dependencies = [ - "atty", - "humantime", - "log", - "regex", - "termcolor", -] - [[package]] name = "event-listener" version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71" -[[package]] -name = "fastrand" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" -dependencies = [ - "instant", -] - [[package]] name = "firestorm" version = "0.5.1" @@ -745,21 +821,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "form_urlencoded" version = "1.0.1" @@ -770,21 +831,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "futures" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - [[package]] name = "futures-channel" version = "0.3.21" @@ -801,17 +847,6 @@ version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" -[[package]] -name = "futures-executor" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - [[package]] name = "futures-intrusive" version = "0.4.0" @@ -823,12 +858,6 @@ dependencies = [ "parking_lot 0.11.2", ] -[[package]] -name = "futures-io" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" - [[package]] name = "futures-macro" version = "0.3.21" @@ -858,13 +887,10 @@ version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" dependencies = [ - "futures-channel", "futures-core", - "futures-io", "futures-macro", "futures-sink", "futures-task", - "memchr", "pin-project-lite", "pin-utils", "slab", @@ -891,6 +917,16 @@ dependencies = [ "wasi 0.11.0+wasi-snapshot-preview1", ] +[[package]] +name = "ghash" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1583cc1656d7839fd3732b80cf4f38850336cdb9b8ded1cd399ca62958de3c99" +dependencies = [ + "opaque-debug", + "polyval", +] + [[package]] name = "gumdrop" version = "0.8.1" @@ -926,7 +962,7 @@ dependencies = [ "indexmap", "slab", "tokio", - "tokio-util", + "tokio-util 0.7.3", "tracing", ] @@ -1001,17 +1037,6 @@ dependencies = [ "itoa", ] -[[package]] -name = "http-body" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - [[package]] name = "http-range" version = "0.1.5" @@ -1036,49 +1061,6 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02296996cb8796d7c6e3bc2d9211b7802812d36999a51bb754123ead7d37d026" -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - -[[package]] -name = "hyper" -version = "0.14.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42dc3c131584288d375f2d07f822b0cb012d8c6fb899a5b9fdb3cb7eb9b6004f" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper-tls" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" -dependencies = [ - "bytes", - "hyper", - "native-tls", - "tokio", - "tokio-native-tls", -] - [[package]] name = "idna" version = "0.2.3" @@ -1115,12 +1097,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "ipnet" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" - [[package]] name = "itertools" version = "0.10.3" @@ -1273,24 +1249,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "native-tls" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd7e2f3618557f980e0b17e8856252eee3c97fa12c54dff0ca290fb6266ca4a9" -dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - [[package]] name = "nom" version = "7.1.1" @@ -1301,40 +1259,6 @@ dependencies = [ "minimal-lexical", ] -[[package]] -name = "num" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b7a8e9be5e039e2ff869df49155f1c06bd01ade2117ec783e56ab0932b67a8f" -dependencies = [ - "num-bigint", - "num-complex", - "num-integer", - "num-iter", - "num-rational", - "num-traits", -] - -[[package]] -name = "num-bigint" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6f7833f2cbf2360a6cfd58cd41a53aa7a90bd4c202f5b1c7dd2ed73c57b2c3" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-complex" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "747d632c0c558b87dbabbe6a82f3b4ae03720d0646ac5b7b4dae89394be5f2c5" -dependencies = [ - "num-traits", -] - [[package]] name = "num-integer" version = "0.1.45" @@ -1345,29 +1269,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-iter" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07" -dependencies = [ - "autocfg", - "num-bigint", - "num-integer", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.15" @@ -1403,63 +1304,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" [[package]] -name = "openssl" -version = "0.10.40" +name = "opaque-debug" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb81a6430ac911acb25fe5ac8f1d2af1b4ea8a4fdfda0f1ee4292af2e2d8eb0e" -dependencies = [ - "bitflags", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "openssl-sys" -version = "0.9.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "835363342df5fba8354c5b453325b110ffd54044e588c539cf2f20a8014e4cb1" -dependencies = [ - "autocfg", - "cc", - "libc", - "pkg-config", - "vcpkg", -] +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "oswilno" version = "0.1.0" dependencies = [ - "actix", - "actix-4-jwt-auth", + "actix 0.13.0", "actix-cors", "actix-files", + "actix-identity", + "actix-redis", "actix-rt", "actix-web", + "argon2", "askama", "chrono", "gumdrop", + "password-hash", + "rand", "serde", "serde_json", "sqlx", @@ -1518,6 +1384,17 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "password-hash" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" +dependencies = [ + "base64ct", + "rand_core", + "subtle", +] + [[package]] name = "paste" version = "1.0.7" @@ -1563,10 +1440,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] -name = "pkg-config" -version = "0.3.25" +name = "polyval" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" +checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] [[package]] name = "ppv-lite86" @@ -1646,6 +1529,21 @@ dependencies = [ "getrandom", ] +[[package]] +name = "redis-async" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76b00c604527d485d7a146d1e324ec1cf0a5ec522acb3d05bf7d51a9c28d7c0c" +dependencies = [ + "bytes", + "futures-channel", + "futures-sink", + "futures-util", + "log", + "tokio", + "tokio-util 0.6.10", +] + [[package]] name = "redox_syscall" version = "0.2.13" @@ -1683,52 +1581,6 @@ version = "0.6.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - -[[package]] -name = "reqwest" -version = "0.11.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b75aa69a3f06bbcc66ede33af2af253c6f7a86b1ca0033f60c580a27074fbf92" -dependencies = [ - "base64", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-tls", - "ipnet", - "js-sys", - "lazy_static", - "log", - "mime", - "native-tls", - "percent-encoding", - "pin-project-lite", - "serde", - "serde_json", - "serde_urlencoded", - "tokio", - "tokio-native-tls", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "winreg", -] - [[package]] name = "ring" version = "0.16.20" @@ -1780,26 +1632,6 @@ version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" -[[package]] -name = "sanitize-filename" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf18934a12018228c5b55a6dae9df5d0641e3566b3630cb46cc55564068e7c2f" -dependencies = [ - "lazy_static", - "regex", -] - -[[package]] -name = "schannel" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" -dependencies = [ - "lazy_static", - "windows-sys", -] - [[package]] name = "scopeguard" version = "1.1.0" @@ -1816,29 +1648,6 @@ dependencies = [ "untrusted", ] -[[package]] -name = "security-framework" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "semver" version = "1.0.11" @@ -1871,7 +1680,6 @@ version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7" dependencies = [ - "indexmap", "itoa", "ryu", "serde", @@ -2101,29 +1909,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "tempfile" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" -dependencies = [ - "cfg-if", - "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", -] - -[[package]] -name = "termcolor" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" -dependencies = [ - "winapi-util", -] - [[package]] name = "thiserror" version = "1.0.31" @@ -2213,31 +1998,9 @@ dependencies = [ "pin-project-lite", "signal-hook-registry", "socket2", - "tokio-macros", "winapi", ] -[[package]] -name = "tokio-macros" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tokio-native-tls" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" -dependencies = [ - "native-tls", - "tokio", -] - [[package]] name = "tokio-rustls" version = "0.23.4" @@ -2260,6 +2023,20 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-util" +version = "0.6.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36943ee01a6d67977dd3f84a5a1d2efeb4ada3a1ae771cadfaa535d9d9fc6507" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "log", + "pin-project-lite", + "tokio", +] + [[package]] name = "tokio-util" version = "0.7.3" @@ -2283,12 +2060,6 @@ dependencies = [ "serde", ] -[[package]] -name = "tower-service" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" - [[package]] name = "tracing" version = "0.1.35" @@ -2371,12 +2142,6 @@ dependencies = [ "tracing-log", ] -[[package]] -name = "try-lock" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" - [[package]] name = "typenum" version = "1.15.0" @@ -2425,6 +2190,16 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" +[[package]] +name = "universal-hash" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" +dependencies = [ + "generic-array", + "subtle", +] + [[package]] name = "untrusted" version = "0.7.1" @@ -2502,28 +2277,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "want" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" -dependencies = [ - "log", - "try-lock", -] - [[package]] name = "wasi" version = "0.10.0+wasi-snapshot-preview1" @@ -2561,18 +2320,6 @@ dependencies = [ "wasm-bindgen-shared", ] -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de9a9cec1733468a8c657e57fa2413d2ae2c0129b95e87c5b72b8ace4d13f31f" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "wasm-bindgen-macro" version = "0.2.81" @@ -2657,15 +2404,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -2715,15 +2453,6 @@ version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" -[[package]] -name = "winreg" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" -dependencies = [ - "winapi", -] - [[package]] name = "zstd" version = "0.11.2+zstd.1.5.2" diff --git a/Cargo.toml b/Cargo.toml index 52a9114..fe73c95 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,14 +4,13 @@ version = "0.1.0" edition = "2021" [dependencies] -actix = "*" -actix-web = "*" -actix-cors = "*" -actix-rt = "*" -actix-files = "*" -# actix-web-4-validator = { version = "3.2.0", default-features = false } -actix-4-jwt-auth = "0.4.2" -# actix-web-security = "*" +actix = { version = "*" } +actix-web = { version = "*" } +actix-cors = { version = "*" } +actix-rt = { version = "*" } +actix-files = { version = "*" } +actix-redis = { version = "0.11.0" } +actix-identity = { version = "0.4.0" } askama = { version = "*" } validator = { version = "0.14", features = ["derive"] } serde = { version = "*", features = ["derive"] } @@ -19,7 +18,10 @@ serde_json = { version = "*" } sqlx = { version = "*", features = ["runtime-actix-rustls", "postgres", "uuid", "chrono"] } uuid = { version = "*", features = ["serde"] } chrono = { version = "*", features = ["serde"] } -gumdrop = "*" -tracing = "*" -tracing-subscriber = "*" -tracing-actix-web = "*" +gumdrop = { version = "*" } +tracing = { version = "*" } +tracing-subscriber = { version = "*" } +tracing-actix-web = { version = "*" } +argon2 = { version = "0.4.1" } +password-hash = { version = "0.4.2" } +rand = { version = "0.8.5", features = [] } diff --git a/assets/templates/account.html b/assets/templates/account.html index a423956..c4c360a 100644 --- a/assets/templates/account.html +++ b/assets/templates/account.html @@ -1,30 +1,15 @@ - - - - OS Wilno - - - - - - - - -
-
-
-

OS Wilno

-
-
-
- - Lokalne Usługi - Aktualności - Konto - - - -
-
- - +{% extends "base.html" %} +{% block content %} +{% match account.as_ref() %} +{% when Some with (a) %} + +{% when None %} + +{% endmatch %} +{% endblock %} diff --git a/assets/templates/base.html b/assets/templates/base.html new file mode 100644 index 0000000..bf9c5e4 --- /dev/null +++ b/assets/templates/base.html @@ -0,0 +1,30 @@ + + + + OS Wilno + + + + + + + {% block head %}{% endblock %} + + +
+
+
+

OS Wilno

+
+
+
+ + Lokalne Usługi + Aktualności + Konto + + {% block content %}{% endblock %} +
+
+ + diff --git a/assets/templates/index.html b/assets/templates/index.html index cce25f8..f680fda 100644 --- a/assets/templates/index.html +++ b/assets/templates/index.html @@ -1,47 +1,23 @@ - - - - OS Wilno - - - - - - - -
-
-
-

OS Wilno

-
-
-
- - Lokalne Usługi - Aktualności - Konto - - - {% for service in services %} - - {% for line in service.description.lines() %} -

{{line}}

- {% endfor %} +{% extends "base.html" %} +{% block content %} + + {% for service in services %} + + {% for line in service.description.lines() %} +

{{line}}

+ {% endfor %} - {% for item in service.items %} - - - {% endfor %} + {% for item in service.items %} + + + {% endfor %} -
- {% endfor %} -
-
-
- - + + {% endfor %} + +{% endblock %} diff --git a/client/dist/app.js b/client/dist/app.js index 2031dcc..26664af 100644 --- a/client/dist/app.js +++ b/client/dist/app.js @@ -3,9 +3,10 @@ const FORM_STYLE = ` form { display: block; } -form.inline { - display: flex; - justify-content: space-between; +form legend { + margin: 16px 0; + font-weight: bold; + font-size: 20px; } form > div { display: block; @@ -102,12 +103,9 @@ class PseudoForm extends HTMLElement { } } const fireFbReady = ()=>{ - for (let c of (b = !0, a))c(); + for (let c of (!0, a))c(); }; -const runFbReady = (c)=>{ - b ? c() : a.push(c); -}; -let a = [], b = !1; +let a = []; customElements.define("form-navigation", class extends HTMLElement { static get observedAttributes() { return [ @@ -133,7 +131,7 @@ customElements.define("form-navigation", class extends HTMLElement { display: none !important; } -
+
@@ -355,19 +353,23 @@ customElements.define("login-form", class extends HTMLElement { customElements.define("ow-account", class extends HTMLElement { static get observedAttributes() { return [ - "mode" + "mode", + "id", + "name", + "email", + "facebook-id" ]; } constructor(){ super(); - let b = this[S] = this.attachShadow({ + let c = this[S] = this.attachShadow({ mode: "closed" }); - b.innerHTML = ` + c.innerHTML = ` -
+ - `, b.querySelector("#switch-login > a").addEventListener("click", (a)=>{ +
+
+ +
+
+ + +
+
+ + +
+
+ + +
+
+ `, c.querySelector("#switch-login > a").addEventListener("click", (a)=>{ a.stopPropagation(), a.preventDefault(), this.mode = "login"; - }), b.querySelector("#switch-register > a").addEventListener("click", (a)=>{ + }), c.querySelector("#switch-register > a").addEventListener("click", (a)=>{ a.stopPropagation(), a.preventDefault(), this.mode = "register"; }); } connectedCallback() { - this.mode = "login"; + "" === this.mode && (this.mode = "login"); } attributeChangedCallback(a, b, c) { - if (b === c) return; + if (b !== c) switch(a){ + case "mode": + this.mode = c; + break; + case "id": + this.id = c; + break; + case "name": + this.name = c; + break; + case "email": + this.email = c; + break; + case "facebook-id": + this.facebook_id = c; + } } get mode() { - return this.getAttribute("mode"); + return this.getAttribute("mode") || ""; } set mode(a) { - a = "login" === a || "register" === a ? a : "login", this.setAttribute("mode", a); + a = [ + "login", + "register", + "display" + ].includes(a) ? a : "login", this.setAttribute("mode", a); + } + get name() { + return this.getAttribute("name") || ""; + } + set name(b) { + this.setAttribute("name", b), this[S].querySelector("#display #name").value = b; + } + get email() { + return this.getAttribute("email") || ""; + } + set email(b) { + this.setAttribute("email", b), this[S].querySelector("#display #email").value = b; + } + get facebook_id() { + return this.getAttribute("facebook-id"); + } + set facebook_id(b) { + this.setAttribute("facebook-id", b), this[S].querySelector("#display #facebook_id").value = b; } }); customElements.define("ow-nav", class extends HTMLElement { @@ -667,7 +731,7 @@ customElements.define("register-basic-form", class extends PseudoForm {
- +
`; let d = c.querySelector("form"); @@ -737,8 +801,8 @@ customElements.define("register-item-form-row", class extends PseudoForm { } get inputs() { return [ - this[S].querySelector("input.item-name").cloneNode(!0), - this[S].querySelector("input.item-price").cloneNode(!0), + this[S].querySelector(".item-name").cloneNode(!0), + this[S].querySelector(".item-price").cloneNode(!0), ]; } updateNames() { @@ -870,6 +934,7 @@ customElements.define("register-submit-form", class extends PseudoForm { +
@@ -890,6 +955,9 @@ customElements.define("register-submit-form", class extends PseudoForm { f.setAttribute("readonly", "readonly"), e.appendChild(f), e.appendChild(document.createElement("price-view")).value = g.value, g.setAttribute("readonly", "readonly"), g.setAttribute("type", "hidden"), e.appendChild(g); } } + set accountType(a) { + this[S].querySelector("#account_type").value = a; + } }); customElements.define("register-user-type", class extends HTMLElement { constructor(){ @@ -961,102 +1029,104 @@ customElements.define("register-user-type", class extends HTMLElement { }); } }); -customElements.define("register-oauth2", class extends HTMLElement { +customElements.define("register-user-form", class extends HTMLElement { static get observedAttributes() { return [ - "fb-connected" + "mode" ]; } constructor(){ super(); - let a = this.attachShadow({ + let c = this[S] = this.attachShadow({ mode: "closed" }); - a.innerHTML = ` - - - -
-Rejestracja adresem e-mail -
- - -
-
- - -
-
- - -
-
- -
-
- - + c.innerHTML = ` + +
+
+ + + + +
+ +
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
+
+ + + +
+
`; + let d = c.querySelector("form"); + c.querySelector("#fb-icon").addEventListener("click", (a)=>{ + a.stopPropagation(), a.preventDefault(), this.mode = "facebook", FB.login((a)=>{ + "connected" === a.status && FB.api("/me?fields=id,name,email", ({ id: a , name: b , email: c , ...e })=>{ + console.log(a, b, c, e), d.querySelector("#email").value = c, d.querySelector("#login").value = b, d.querySelector("#password").value = crypto.randomUUID(), d.querySelector("#facebook_id").value = a, d.submit(); + }); + }, { + scope: "public_profile,email", + return_scopes: !0 + }); + }), c.querySelector("#email-icon").addEventListener("click", (a)=>{ + a.stopPropagation(), a.preventDefault(), this.mode = "email"; + }); } connectedCallback() { - runFbReady(()=>{ - FB.getLoginStatus(({ status: a })=>{ - "connected" !== a ? FB.login() : this.setAttribute("fb-connected", "1"); - }); - }); + this.mode = ""; + } + attributeChangedCallback(a, b, c) { + b !== c && "mode" === a && ("email" === c || "facebook" === c || "" === c) && (this.mode = c); + } + get mode() { + return this.getAttribute("mode") || ""; + } + set mode(a) { + this.setAttribute("mode", a); } }); let c = (a, b)=>{ @@ -1087,7 +1157,7 @@ customElements.define("register-form", class extends HTMLElement { :host([step="2"]) #step-2 { display: block; } :host([step="3"]) #step-3 { display: block; } :host([step="4"]) #step-4 { display: block; } - :host([step="1000"]) #step-1000 { display: block; } + :host([step="40"]) #step-40 { display: block; } ${FORM_STYLE} @@ -1105,31 +1175,22 @@ customElements.define("register-form", class extends HTMLElement { display: none; } +
+
- - - - - - - - - - - - - - - - - + + + + + +
`; let e = d.querySelector("#step-4"); this[S].addEventListener("account:type:user", (a)=>{ - a.stopPropagation(), this.step = 1000; + a.stopPropagation(), e.accountType = "User", this.step = 40; }), this[S].addEventListener("account:type:local-service", (a)=>{ - a.stopPropagation(), this.step = 1; + a.stopPropagation(), e.accountType = "Business", this.step = 1; }), this[S].addEventListener("form:next", (a)=>{ a.stopPropagation(); let b = d.querySelector(`#step-${this.step}`); @@ -1154,14 +1215,15 @@ customElements.define("register-form", class extends HTMLElement { a < 0 || this.setAttribute("step", a); } }); -if (window.fbAsyncInit = ()=>{ - FB.init({ - appId: "1293538251053124", - cookie: !0, - xfbml: !0, - version: "v14.0" - }), FB.AppEvents.logPageView(), fireFbReady(); -}, !document.querySelector("#facebook-jssdk")) { - let b1 = document.createElement("script"); - b1.id = "facebook-jssdk", b1.src = "https://connect.facebook.net/en_US/sdk.js", document.head.appendChild(b1); +if (!document.querySelector("#facebook-jssdk")) { + window.fbAsyncInit = ()=>{ + FB.init({ + appId: "1293538251053124", + cookie: !0, + xfbml: !0, + version: "v14.0" + }), FB.AppEvents.logPageView(), fireFbReady(); + }; + let b = document.createElement("script"); + b.id = "facebook-jssdk", b.src = "https://connect.facebook.net/en_US/sdk.js", document.head.appendChild(b); } diff --git a/client/dist/app.js.map b/client/dist/app.js.map index 1bcef7c..b5bf1bd 100644 --- a/client/dist/app.js.map +++ b/client/dist/app.js.map @@ -1 +1 @@ -{"version":3,"sources":["/home/eraden/code/eraden/oswilno/client/src/shared.js","/home/eraden/code/eraden/oswilno/client/src/form-navigation.js","/home/eraden/code/eraden/oswilno/client/src/local-service.js","/home/eraden/code/eraden/oswilno/client/src/local-service-item.js","/home/eraden/code/eraden/oswilno/client/src/local-services.js","/home/eraden/code/eraden/oswilno/client/src/login-form.js","/home/eraden/code/eraden/oswilno/client/src/ow-account.js","/home/eraden/code/eraden/oswilno/client/src/ow-nav.js","/home/eraden/code/eraden/oswilno/client/src/ow-path.js","/home/eraden/code/eraden/oswilno/client/src/price/price-view.js","/home/eraden/code/eraden/oswilno/client/src/price/price-input.js","/home/eraden/code/eraden/oswilno/client/src/register-form/register-basic-form.js","/home/eraden/code/eraden/oswilno/client/src/register-form/register-item-form-row.js","/home/eraden/code/eraden/oswilno/client/src/register-form/register-items-form.js","/home/eraden/code/eraden/oswilno/client/src/register-form/register-company-form.js","/home/eraden/code/eraden/oswilno/client/src/register-form/register-submit-form.js","/home/eraden/code/eraden/oswilno/client/src/register-form/register-user-type.js","/home/eraden/code/eraden/oswilno/client/src/register-form/register-oauth2.js","/home/eraden/code/eraden/oswilno/client/src/register-form.js","/home/eraden/code/eraden/oswilno/client/src/app.js"],"sourcesContent":["export const S = Symbol();\n\nexport const FORM_STYLE = `\nform {\n display: block;\n}\nform.inline {\n display: flex;\n justify-content: space-between;\n}\nform > div {\n display: block;\n margin-bottom: 1rem;\n}\ninput, textarea {\n font-size: 16px;\n\n border: none;\n border-bottom-style: none;\n border-bottom-width: medium;\n border-bottom: 1px solid rgba(0,0,0,.1);\n border-radius: 2px;\n padding: 0;\n \n height: 36px;\n background: #fff;\n color: rgba(0,0,0,.8);\n font-size: 14px;\n \n box-shadow: none !important;\n\n display: block;\n width: 100%;\n height: calc(1.5em + 0.75rem + 2px);\n padding: .375rem .75rem;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n background-clip: padding-box;\n transition: border-color .15s ease-in-out , -webkit-box-shadow .15s ease-in-out;\n transition: border-color .15s ease-in-out , box-shadow .15s ease-in-out;\n transition: border-color .15s ease-in-out , box-shadow .15s ease-in-out , -webkit-box-shadow .15s ease-in-out;\n}\ninput[type=\"text\"],\ninput[type=\"number\"],\ninput[type=\"email\"],\ninput[type=\"password\"],\ntextarea {\n width: calc(100% - 1.5rem - 2px);\n}\nlabel {\n color: #000;\n text-transform: uppercase;\n font-size: 12px;\n font-weight: 600;\n \n display: inline-block;\n margin-bottom: .5rem;\n}\ninput[type=\"button\"], input[type=\"submit\"] {\n padding: 12px 16px;\n cursor: pointer;\n border: none;\n border-width: 1px;\n border-radius: 5px;\n font-size: 14px;\n font-weight: 400;\n box-shadow: 0 10px 20px -6px rgba(0,0,0,.12);\n position: relative;\n margin-bottom: 20px;\n transition: .3s;\n \n background: #46b5d1;\n color: #fff;\n \n display: inline-block;\n font-weight: 400;\n text-align: center;\n vertical-align: middle;\n user-select: none;\n padding: .375rem .75rem;\n font-size: 1rem;\n line-height: 1.5;\n transition: color .15s ease-in-out,\n background-color .15s ease-in-out,\n border-color .15s ease-in-out,\n box-shadow .15s ease-in-out,\n width: auto;\n height: calc(1.5em + 0.75rem + 2px);\n padding: .375rem .75rem;\n}\n`;\n\nexport class PseudoForm extends HTMLElement {\n reportValidity() {\n return this[S].querySelector('form').reportValidity();\n }\n\n checkValidity() {\n return this[S].querySelector('form').checkValidity();\n }\n\n get elements() {\n return this[S].querySelector('form').elements;\n }\n}\n\nexport const fireFbReady = () => {\n fbReady = true;\n for (const fn of fbQueue) fn();\n};\nexport const runFbReady = (fn) => {\n if (!fbReady) fbQueue.push(fn);\n else fn();\n};\nconst fbQueue = [];\nlet fbReady = false;\n","import { S, FORM_STYLE } from \"./shared\";\n\ncustomElements.define('form-navigation', class extends HTMLElement {\n static get observedAttributes() {\n return ['next', 'prev']\n }\n\n constructor() {\n super();\n\n const shadow = this[S] = this.attachShadow({ mode: \"closed\" });\n shadow.innerHTML = `\n \n
\n
\n \n \n
\n
\n `;\n shadow.querySelector('#prev').addEventListener('click', ev => {\n ev.stopPropagation();\n ev.preventDefault();\n this.dispatchEvent(new CustomEvent('form:prev', {\n bubbles: true,\n composed: true,\n detail: this.parentElement\n }));\n });\n shadow.querySelector('#next').addEventListener('click', ev => {\n ev.stopPropagation();\n ev.preventDefault();\n this.dispatchEvent(new CustomEvent('form:next', {\n bubbles: true,\n composed: true,\n detail: this.parentElement\n }));\n });\n }\n\n attributeChangedCallback(name, oldV, newV) {\n if (oldV === newV) return;\n switch (name) {\n case 'next': {\n this[S].querySelector('#next').className = newV === 'hidden' ? 'hidden' : '';\n break;\n }\n case 'prev': {\n this[S].querySelector('#prev').className = newV === 'hidden' ? 'hidden' : '';\n break;\n }\n }\n }\n});\n","import { S } from \"./shared\";\n\ncustomElements.define('local-service', class extends HTMLElement {\n static get observedAttributes() {\n return ['name', 'service-id', 'state']\n }\n\n constructor() {\n super();\n const shadow = this[S] = this.attachShadow({ mode: 'closed' });\n shadow.innerHTML = `\n \n

\n \n
\n \n
\n `;\n }\n\n connectedCallback() {\n this[S].querySelector('#name').textContent = this.getAttribute('name');\n }\n\n attributeChangedCallback(name, oldV, newV) {\n if (oldV === newV) return;\n switch (name) {\n case 'name':\n return this[S].querySelector('#name').textContent = newV;\n }\n }\n\n get name() {\n return this.getAttribute('name') || ''\n }\n});\n","import { S } from \"./shared\";\n\ncustomElements.define('local-service-item', class extends HTMLElement {\n static get observedAttributes() {\n return ['name', 'price']\n }\n\n constructor() {\n super();\n const shadow = this[S] = this.attachShadow({ mode: 'closed' });\n shadow.innerHTML = `\n \n
\n

\n \n
\n `;\n }\n\n connectedCallback() {\n this[S].querySelector('#name').textContent = this.getAttribute('name');\n this[S].querySelector('#price').value = this.price();\n }\n\n attributeChangedCallback(name, oldV, newV) {\n if (oldV === newV) return;\n switch (name) {\n case 'name':\n return this[S].querySelector('#name').textContent = newV;\n case 'price':\n return this[S].querySelector('#price').value = newV;\n }\n }\n\n price(s) {\n const n = parseInt(s || this.getAttribute('price'));\n return isNaN(n) ? 0 : n;\n }\n});\n","import { S } from \"./shared\";\n\ncustomElements.define('local-services', class extends HTMLElement {\n static get observedAttributes() {\n return ['filter']\n }\n\n constructor() {\n super();\n const shadow = this[S] = this.attachShadow({ mode: 'closed' });\n shadow.innerHTML = `\n \n
\n \n
\n
\n \n
\n `;\n {\n const filter = shadow.querySelector('#filter');\n let t = null;\n filter.addEventListener('change', ev => {\n ev.stopPropagation();\n this.filter = ev.target.value;\n });\n filter.addEventListener('keyup', ev => {\n ev.stopPropagation();\n const value = ev.target.value;\n\n if (t) clearTimeout(t);\n t = setTimeout(() => {\n this.filter = value;\n t = null;\n }, 1000 / 3);\n });\n }\n }\n\n connectedCallback() {\n this.filter = this.getAttribute('filter');\n }\n\n attributeChangedCallback(name, oldV, newV) {\n if (oldV === newV) return;\n switch (name) {\n case 'filter':\n return this.filter = newV;\n }\n }\n\n get filter() {\n return this.getAttribute('filter');\n }\n\n set filter(value) {\n if (!value || value === '') {\n this.removeAttribute('filter');\n for (const el of this.querySelectorAll('local-service')) {\n el.removeAttribute('local-services-visible');\n }\n } else {\n this.setAttribute('filter', value);\n for (const el of this.querySelectorAll('local-service')) {\n if (!el.name) continue;\n if (el.name.includes(value)) {\n el.setAttribute('local-services-visible', 'visible');\n } else {\n el.setAttribute('local-services-visible', 'invisible');\n }\n }\n }\n }\n});\n","import { FORM_STYLE, S } from \"./shared\";\n\ncustomElements.define('login-form', class extends HTMLElement {\n static get observedAttributes() {\n return []\n }\n\n constructor() {\n super();\n const shadow = this[S] = this.attachShadow({ mode: 'closed' });\n shadow.innerHTML = `\n \n
\n
\n \n \n
\n
\n \n \n
\n
\n \n
\n
\n `;\n }\n\n connectedCallback() {\n }\n\n attributeChangedCallback(name, oldV, newV) {\n if (oldV === newV) return;\n switch (name) {\n }\n }\n});\n","import { S } from \"./shared\";\n\ncustomElements.define('ow-account', class extends HTMLElement {\n static get observedAttributes() {\n return ['mode']\n }\n\n constructor() {\n super();\n const shadow = this[S] = this.attachShadow({ mode: 'closed' });\n shadow.innerHTML = `\n \n
\n \n \n
\n Nie masz konta? Utwórz nowe\n
\n
\n Masz konta? Zaloguj się\n
\n
\n `;\n shadow.querySelector('#switch-login > a').addEventListener('click', ev => {\n ev.stopPropagation();\n ev.preventDefault();\n this.mode = 'login';\n });\n shadow.querySelector('#switch-register > a').addEventListener('click', ev => {\n ev.stopPropagation();\n ev.preventDefault();\n this.mode = 'register';\n });\n }\n\n connectedCallback() {\n this.mode = 'login';\n }\n\n attributeChangedCallback(name, oldV, newV) {\n if (oldV === newV) return;\n switch (name) {\n }\n }\n\n get mode() {\n return this.getAttribute('mode');\n }\n\n set mode(value) {\n value = value === 'login' || value === 'register' ? value : 'login';\n this.setAttribute('mode', value);\n }\n});\n","import { S } from \"./shared\";\n\ncustomElements.define('ow-nav', class extends HTMLElement {\n constructor() {\n super();\n const shadow = this[S] = this.attachShadow({ mode: 'closed' });\n shadow.innerHTML = `\n \n
\n \n
\n `;\n }\n});\n","import { S } from \"./shared\";\n\ncustomElements.define('ow-path', class extends HTMLElement {\n static get observedAttributes() {\n return ['selected', 'path'];\n }\n\n constructor() {\n super();\n const shadow = this[S] = this.attachShadow({ mode: 'closed' });\n shadow.innerHTML = `\n \n \n `;\n }\n\n connectedCallback() {\n this.selected = this.getAttribute('selected');\n }\n\n attributeChangedCallback(name, oldV, newV) {\n if (oldV === newV) return;\n switch (name) {\n case 'selected':\n return this.selected = newV;\n case 'path':\n return this.path = newV;\n }\n }\n\n get selected() {\n return this.getAttribute('selected') === 'selected';\n }\n\n set selected(value) {\n if (value === 'selected') this.setAttribute('selected', 'selected');\n else this.removeAttribute('selected');\n }\n\n get path() {\n return this.getAttribute('path') || ''\n }\n\n set path(value) {\n if (!value || value === '') {\n this.removeAttribute('path');\n return;\n }\n this.setAttribute('path', value);\n this[S].querySelector('a').setAttribute('href', value);\n }\n});\n","import { S } from \"../shared\";\n\ncustomElements.define('price-view', class extends HTMLElement {\n static get observedAttributes() {\n return ['value', 'currency']\n }\n\n constructor() {\n super();\n const shadow = this[S] = this.attachShadow({ mode: 'closed' });\n shadow.innerHTML = `\n \n \n `;\n }\n\n connectedCallback() {\n this[S].querySelector('#price').textContent = this.formatted;\n }\n\n attributeChangedCallback(name, oldV, newV) {\n if (oldV === newV) return;\n switch (name) {\n case 'price': {\n this.value = newV;\n break;\n }\n }\n }\n\n get formatted() {\n let v = this.value;\n let major = Math.ceil(v / 100);\n let minor = v % 100;\n let formatted = `${ major },${ minor < 10 ? `0${ minor }` : minor }`;\n return `${ formatted }${ this.currency }`\n }\n\n get value() {\n const n = parseInt(this.getAttribute('value'));\n return isNaN(n) ? 0 : n;\n }\n\n set value(v) {\n this.setAttribute('value', v);\n this[S].querySelector('#price').textContent = this.formatted;\n }\n\n get currency() {\n return this.getAttribute('currency') || 'PLN';\n }\n});\n","import { S, FORM_STYLE } from \"../shared\";\n\ncustomElements.define('price-input', class extends HTMLElement {\n static get observedAttributes() {\n return ['value', 'currency', 'required', 'name']\n }\n\n constructor() {\n super();\n const shadow = this[S] = this.attachShadow({ mode: 'closed' });\n shadow.innerHTML = `\n \n
\n \n \n
\n `;\n }\n\n connectedCallback() {\n this[S].querySelector('#currency').textContent = this.currency;\n // this[S].querySelector('#price').textContent = this.formatted;\n }\n\n attributeChangedCallback(name, oldV, newV) {\n if (oldV === newV) return;\n const price = this[S].querySelector('#price');\n switch (name) {\n case 'price': {\n this.value = newV;\n break;\n }\n case 'currency': {\n this.currency = newV;\n break;\n }\n case 'required': {\n newV\n ? price.setAttribute('required', 'required')\n : price.removeAttribute('required');\n break;\n }\n case 'readonly': {\n newV\n ? price.setAttribute('readonly', 'readonly')\n : price.removeAttribute('readonly');\n break;\n }\n case 'name': {\n break;\n }\n }\n }\n\n get value() {\n return this[S].querySelector('#price').value * 100;\n }\n\n set value(v) {\n this.setAttribute('value', v);\n this[S].querySelector('#price').value = v;\n }\n\n get currency() {\n return this.getAttribute('currency') || 'PLN';\n }\n\n set currency(value) {\n this.setAttribute('currency', value);\n this[S].querySelector('#currency').textContent = this.currency;\n }\n\n reportValidity() {\n return this[S].querySelector('input').reportValidity();\n }\n\n get name() {\n return this.getAttribute('name');\n }\n\n set name(value) {\n this.setAttribute('name', value);\n }\n});\n","import { FORM_STYLE, S, PseudoForm } from \"../shared\";\n\ncustomElements.define('register-basic-form', class extends PseudoForm {\n constructor() {\n super();\n\n const shadow = this[S] = this.attachShadow({ mode: \"closed\" });\n\n shadow.innerHTML = `\n \n
\n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n \n
\n `;\n\n const form = shadow.querySelector('form');\n form.addEventListener('submit', ev => {\n ev.preventDefault();\n ev.stopPropagation();\n this.dispatchEvent(new CustomEvent('form:next', { bubbles: true, composed: true, detail: form }));\n })\n }\n});\n","import { S, FORM_STYLE, PseudoForm } from \"../shared\";\n\ncustomElements.define('register-item-form-row', class extends PseudoForm {\n static get observedAttributes() {\n return ['idx', 'name']\n }\n\n constructor() {\n super();\n this[S] = this.attachShadow({ mode: 'closed' });\n\n this.addEventListener('item:removed', () => {\n this.setAttribute('removed', 'removed');\n const parent = this.parentElement;\n this.remove();\n parent.dispatchEvent(new CustomEvent('item:removed', { bubbles: true, composed: true }));\n });\n }\n\n connectedCallback() {\n const idx = this.getAttribute('idx');\n this[S].innerHTML = `\n \n
\n
\n \n \n
\n
\n \n \n \n
\n
\n
\n `;\n this[S].querySelector('form').addEventListener('submit', ev => {\n ev.preventDefault();\n ev.stopPropagation();\n this.reportValidity();\n });\n this[S].querySelector('.remove').addEventListener('click', ev => {\n ev.preventDefault();\n ev.stopPropagation();\n\n this.dispatchEvent(new CustomEvent('item:removed', { bubbles: true, composed: false }));\n });\n }\n\n attributeChangedCallback(name, oldV, newV) {\n if (oldV === newV) return;\n switch (name) {\n case 'idx': {\n this.updateNames();\n break;\n }\n }\n }\n\n\n get inputs() {\n return [\n this[S].querySelector('input.item-name').cloneNode(true),\n this[S].querySelector('input.item-price').cloneNode(true),\n ];\n }\n\n updateNames() {\n const idx = this.getAttribute('idx');\n for (const el of this[S].querySelectorAll('.field')) {\n const id = el.id;\n el.querySelector('input, price-input').setAttribute('name', `items[${ idx }][${ id }]`);\n }\n }\n\n get idx() {\n return this.getAttribute('idx');\n }\n\n set idx(idx) {\n this.setAttribute('idx', idx);\n }\n\n reportValidity() {\n return super.reportValidity() && this[S].querySelector('price-input').reportValidity();\n }\n});\n","import { FORM_STYLE, S, PseudoForm } from \"../shared\";\n\nimport \"./register-item-form-row\"\n\nconst updateItems = (form) => {\n let idx = 0;\n for (const el of form.querySelectorAll('register-item-form-row')) {\n el.idx = idx++;\n }\n return idx;\n}\n\ncustomElements.define('register-items-form', class extends PseudoForm {\n static get observedAttributes() {\n return []\n }\n\n constructor() {\n super();\n const shadow = this[S] = this.attachShadow({ mode: 'closed' });\n shadow.innerHTML = `\n \n
\n
\n \n
\n
\n \n
\n \n
\n `;\n this.addEventListener('item:removed', ev => {\n ev.stopPropagation();\n updateItems(this)\n });\n this.addEventListener('form:next', ev => {\n for (const el of this.querySelectorAll('item-form-row')) {\n if (!el.reportValidity()) {\n ev.stopPropagation();\n ev.preventDefault();\n }\n }\n });\n shadow.querySelector('#add-item').addEventListener('click', ev => {\n ev.stopPropagation();\n ev.preventDefault();\n this.appendChild(document.createElement('register-item-form-row'));\n updateItems(this)\n });\n }\n\n get inputs() {\n return [...this.querySelectorAll(\"register-item-form-row\")].map(form => form.inputs)\n }\n});\n","import { FORM_STYLE, S, PseudoForm } from \"../shared\";\n\ncustomElements.define('register-company-form', class extends PseudoForm {\n constructor() {\n super();\n\n const shadow = this[S] = this.attachShadow({mode: \"closed\"});\n\n shadow.innerHTML = `\n \n
\n
\n \n
\n
\n \n \n
\n \n
\n `;\n }\n})\n","import { FORM_STYLE, S, PseudoForm } from \"../shared\";\n\ncustomElements.define('register-submit-form', class extends PseudoForm {\n constructor() {\n super();\n\n const shadow = this[S] = this.attachShadow({ mode: \"closed\" });\n\n shadow.innerHTML = `\n \n
\n
\n \n \n \n \n \n
\n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n
\n
\n \n
\n \n \n
\n
\n `;\n }\n\n updateField(name, value) {\n this[S].querySelector(`[id=\"hidden-${ name }\"]`).value = value;\n this[S].querySelector(`[id=\"preview-${ name }\"]`).value = value;\n }\n\n setItems(items) {\n const host = this[S].querySelector('#items');\n host.innerHTML = ``;\n for (const row of items) {\n const el = host.appendChild(document.createElement('div'));\n const [name, price] = row;\n\n name.setAttribute('readonly', 'readonly');\n el.appendChild(name);\n\n el.appendChild(document.createElement('price-view')).value = price.value;\n price.setAttribute('readonly', 'readonly');\n price.setAttribute('type', 'hidden');\n el.appendChild(price);\n }\n }\n});\n","customElements.define('register-user-type', class extends HTMLElement {\n constructor() {\n super();\n\n const shadow = this.attachShadow({ mode: \"closed\" });\n\n shadow.innerHTML = `\n \n
\n \n
\n `;\n\n const user = shadow.querySelector('#user');\n user.addEventListener('click', ev => {\n ev.preventDefault();\n ev.stopPropagation();\n this.dispatchEvent(new CustomEvent('account:type:user', { bubbles: true, composed: true }));\n });\n const service = shadow.querySelector('#local-service');\n service.addEventListener('click', ev => {\n ev.preventDefault();\n ev.stopPropagation();\n this.dispatchEvent(new CustomEvent('account:type:local-service', { bubbles: true, composed: true }));\n });\n }\n});\n","import { runFbReady } from \"../shared\";\n\ncustomElements.define('register-oauth2', class extends HTMLElement {\n static get observedAttributes() {\n return ['fb-connected']\n }\n constructor() {\n super();\n\n const shadow = this.attachShadow({ mode: \"closed\" });\n shadow.innerHTML = `\n \n \n\n
\nRejestracja adresem e-mail\n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n
\n \n
\n
\n\n\n `;\n }\n\n connectedCallback() {\n runFbReady(() => {\n FB.getLoginStatus(({ status }) => {\n if (status !== 'connected')\n FB.login();\n else\n this.setAttribute('fb-connected', '1');\n });\n });\n }\n});\n","import { S, FORM_STYLE } from \"./shared\";\n\nimport \"./register-form/register-basic-form\";\nimport \"./register-form/register-item-form-row.js\";\nimport \"./register-form/register-items-form.js\";\nimport \"./register-form/register-company-form\";\nimport \"./register-form/register-submit-form\";\nimport \"./register-form/register-user-type\";\nimport \"./register-form/register-oauth2\";\n\nconst copyForm = (form, finalForm) => {\n form.reportValidity();\n\n for (const el of form.elements) {\n if (el.name === '') continue;\n if (!el.reportValidity()) {\n return false;\n }\n }\n const inputs = form.inputs;\n if (inputs)\n finalForm.setItems(inputs);\n else\n for (const el of form.elements) {\n if (el.name === '') continue;\n finalForm.updateField(el.name, el.value);\n }\n return true;\n};\n\ncustomElements.define('register-form', class extends HTMLElement {\n static get observedAttributes() {\n return ['step']\n }\n\n constructor() {\n super();\n const shadow = this[S] = this.attachShadow({ mode: 'closed' });\n shadow.innerHTML = `\n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n `;\n\n const finalForm = shadow.querySelector('#step-4');\n this[S].addEventListener('account:type:user', ev => {\n ev.stopPropagation();\n this.step = 1000;\n });\n this[S].addEventListener('account:type:local-service', ev => {\n ev.stopPropagation();\n this.step = 1;\n });\n this[S].addEventListener('form:next', ev => {\n ev.stopPropagation();\n const form = shadow.querySelector(`#step-${ this.step }`);\n if (copyForm(form, finalForm)) {\n this.step = this.step + 1;\n }\n });\n this[S].addEventListener('form:prev', ev => {\n ev.stopPropagation();\n this.step = this.step - 1;\n });\n {\n const el = finalForm;\n el.addEventListener('submit', ev => {\n ev.preventDefault();\n ev.stopPropagation();\n });\n }\n }\n\n connectedCallback() {\n this.step = 0;\n }\n\n attributeChangedCallback(name, oldV, newV) {\n if (oldV === newV) return;\n switch (name) {\n }\n }\n\n get step() {\n const step = parseInt(this.getAttribute('step'));\n return isNaN(step) ? 1 : step;\n }\n\n set step(n) {\n if (n < 0) return;\n this.setAttribute('step', n);\n }\n});\n","import \"./form-navigation.js\";\nimport \"./local-service.js\";\nimport \"./local-service-item.js\";\nimport \"./local-services.js\";\nimport \"./login-form.js\";\nimport \"./ow-account.js\";\nimport \"./ow-nav.js\";\nimport \"./ow-path.js\";\nimport \"./price/price-view\";\nimport \"./price/price-input\";\nimport \"./register-form.js\";\nimport { fireFbReady } from \"./shared.js\";\n\nwindow.fbAsyncInit = () => {\n FB.init({\n appId : '1293538251053124',\n cookie : true,\n xfbml : true,\n version : 'v14.0'\n });\n FB.AppEvents.logPageView();\n\tfireFbReady();\n};\n\n{\n if (!document.querySelector('#facebook-jssdk')) {\n const js = document.createElement('script');\n js.id = 'facebook-jssdk';\n js.src = \"https://connect.facebook.net/en_US/sdk.js\";\n document.head.appendChild(js);\n }\n}\n"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"sources":["/home/eraden/code/eraden/oswilno-light/client/src/shared.js","/home/eraden/code/eraden/oswilno-light/client/src/form-navigation.js","/home/eraden/code/eraden/oswilno-light/client/src/local-service.js","/home/eraden/code/eraden/oswilno-light/client/src/local-service-item.js","/home/eraden/code/eraden/oswilno-light/client/src/local-services.js","/home/eraden/code/eraden/oswilno-light/client/src/login-form.js","/home/eraden/code/eraden/oswilno-light/client/src/ow-account.js","/home/eraden/code/eraden/oswilno-light/client/src/ow-nav.js","/home/eraden/code/eraden/oswilno-light/client/src/ow-path.js","/home/eraden/code/eraden/oswilno-light/client/src/price/price-view.js","/home/eraden/code/eraden/oswilno-light/client/src/price/price-input.js","/home/eraden/code/eraden/oswilno-light/client/src/register-form/register-basic-form.js","/home/eraden/code/eraden/oswilno-light/client/src/register-form/register-item-form-row.js","/home/eraden/code/eraden/oswilno-light/client/src/register-form/register-items-form.js","/home/eraden/code/eraden/oswilno-light/client/src/register-form/register-company-form.js","/home/eraden/code/eraden/oswilno-light/client/src/register-form/register-submit-form.js","/home/eraden/code/eraden/oswilno-light/client/src/register-form/register-user-type.js","/home/eraden/code/eraden/oswilno-light/client/src/register-form/register-user-form.js","/home/eraden/code/eraden/oswilno-light/client/src/register-form.js","/home/eraden/code/eraden/oswilno-light/client/src/app.js"],"sourcesContent":["export const S = Symbol();\n\nexport const FORM_STYLE = `\nform {\n display: block;\n}\nform legend {\n margin: 16px 0;\n font-weight: bold;\n font-size: 20px;\n}\nform > div {\n display: block;\n margin-bottom: 1rem;\n}\ninput, textarea {\n font-size: 16px;\n\n border: none;\n border-bottom-style: none;\n border-bottom-width: medium;\n border-bottom: 1px solid rgba(0,0,0,.1);\n border-radius: 2px;\n padding: 0;\n \n height: 36px;\n background: #fff;\n color: rgba(0,0,0,.8);\n font-size: 14px;\n \n box-shadow: none !important;\n\n display: block;\n width: 100%;\n height: calc(1.5em + 0.75rem + 2px);\n padding: .375rem .75rem;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n background-clip: padding-box;\n transition: border-color .15s ease-in-out , -webkit-box-shadow .15s ease-in-out;\n transition: border-color .15s ease-in-out , box-shadow .15s ease-in-out;\n transition: border-color .15s ease-in-out , box-shadow .15s ease-in-out , -webkit-box-shadow .15s ease-in-out;\n}\ninput[type=\"text\"],\ninput[type=\"number\"],\ninput[type=\"email\"],\ninput[type=\"password\"],\ntextarea {\n width: calc(100% - 1.5rem - 2px);\n}\nlabel {\n color: #000;\n text-transform: uppercase;\n font-size: 12px;\n font-weight: 600;\n \n display: inline-block;\n margin-bottom: .5rem;\n}\ninput[type=\"button\"], input[type=\"submit\"] {\n padding: 12px 16px;\n cursor: pointer;\n border: none;\n border-width: 1px;\n border-radius: 5px;\n font-size: 14px;\n font-weight: 400;\n box-shadow: 0 10px 20px -6px rgba(0,0,0,.12);\n position: relative;\n margin-bottom: 20px;\n transition: .3s;\n \n background: #46b5d1;\n color: #fff;\n \n display: inline-block;\n font-weight: 400;\n text-align: center;\n vertical-align: middle;\n user-select: none;\n padding: .375rem .75rem;\n font-size: 1rem;\n line-height: 1.5;\n transition: color .15s ease-in-out,\n background-color .15s ease-in-out,\n border-color .15s ease-in-out,\n box-shadow .15s ease-in-out,\n width: auto;\n height: calc(1.5em + 0.75rem + 2px);\n padding: .375rem .75rem;\n}\n`;\n\nexport class PseudoForm extends HTMLElement {\n reportValidity() {\n return this[S].querySelector('form').reportValidity();\n }\n\n checkValidity() {\n return this[S].querySelector('form').checkValidity();\n }\n\n get elements() {\n return this[S].querySelector('form').elements;\n }\n}\n\nexport const fireFbReady = () => {\n fbReady = true;\n for (const fn of fbQueue) fn();\n};\nexport const runFbReady = (fn) => {\n if (!fbReady) fbQueue.push(fn);\n else fn();\n};\nconst fbQueue = [];\nlet fbReady = false;\n","import { S, FORM_STYLE } from \"./shared\";\n\ncustomElements.define('form-navigation', class extends HTMLElement {\n static get observedAttributes() {\n return ['next', 'prev']\n }\n\n constructor() {\n super();\n\n const shadow = this[S] = this.attachShadow({ mode: \"closed\" });\n shadow.innerHTML = `\n \n
\n
\n \n \n
\n
\n `;\n shadow.querySelector('#prev').addEventListener('click', ev => {\n ev.stopPropagation();\n ev.preventDefault();\n this.dispatchEvent(new CustomEvent('form:prev', {\n bubbles: true,\n composed: true,\n detail: this.parentElement\n }));\n });\n shadow.querySelector('#next').addEventListener('click', ev => {\n ev.stopPropagation();\n ev.preventDefault();\n this.dispatchEvent(new CustomEvent('form:next', {\n bubbles: true,\n composed: true,\n detail: this.parentElement\n }));\n });\n }\n\n attributeChangedCallback(name, oldV, newV) {\n if (oldV === newV) return;\n switch (name) {\n case 'next': {\n this[S].querySelector('#next').className = newV === 'hidden' ? 'hidden' : '';\n break;\n }\n case 'prev': {\n this[S].querySelector('#prev').className = newV === 'hidden' ? 'hidden' : '';\n break;\n }\n }\n }\n});\n","import { S } from \"./shared\";\n\ncustomElements.define('local-service', class extends HTMLElement {\n static get observedAttributes() {\n return ['name', 'service-id', 'state']\n }\n\n constructor() {\n super();\n const shadow = this[S] = this.attachShadow({ mode: 'closed' });\n shadow.innerHTML = `\n \n

\n \n
\n \n
\n `;\n }\n\n connectedCallback() {\n this[S].querySelector('#name').textContent = this.getAttribute('name');\n }\n\n attributeChangedCallback(name, oldV, newV) {\n if (oldV === newV) return;\n switch (name) {\n case 'name':\n return this[S].querySelector('#name').textContent = newV;\n }\n }\n\n get name() {\n return this.getAttribute('name') || ''\n }\n});\n","import { S } from \"./shared\";\n\ncustomElements.define('local-service-item', class extends HTMLElement {\n static get observedAttributes() {\n return ['name', 'price']\n }\n\n constructor() {\n super();\n const shadow = this[S] = this.attachShadow({ mode: 'closed' });\n shadow.innerHTML = `\n \n
\n

\n \n
\n `;\n }\n\n connectedCallback() {\n this[S].querySelector('#name').textContent = this.getAttribute('name');\n this[S].querySelector('#price').value = this.price();\n }\n\n attributeChangedCallback(name, oldV, newV) {\n if (oldV === newV) return;\n switch (name) {\n case 'name':\n return this[S].querySelector('#name').textContent = newV;\n case 'price':\n return this[S].querySelector('#price').value = newV;\n }\n }\n\n price(s) {\n const n = parseInt(s || this.getAttribute('price'));\n return isNaN(n) ? 0 : n;\n }\n});\n","import { S } from \"./shared\";\n\ncustomElements.define('local-services', class extends HTMLElement {\n static get observedAttributes() {\n return ['filter']\n }\n\n constructor() {\n super();\n const shadow = this[S] = this.attachShadow({ mode: 'closed' });\n shadow.innerHTML = `\n \n
\n \n
\n
\n \n
\n `;\n {\n const filter = shadow.querySelector('#filter');\n let t = null;\n filter.addEventListener('change', ev => {\n ev.stopPropagation();\n this.filter = ev.target.value;\n });\n filter.addEventListener('keyup', ev => {\n ev.stopPropagation();\n const value = ev.target.value;\n\n if (t) clearTimeout(t);\n t = setTimeout(() => {\n this.filter = value;\n t = null;\n }, 1000 / 3);\n });\n }\n }\n\n connectedCallback() {\n this.filter = this.getAttribute('filter');\n }\n\n attributeChangedCallback(name, oldV, newV) {\n if (oldV === newV) return;\n switch (name) {\n case 'filter':\n return this.filter = newV;\n }\n }\n\n get filter() {\n return this.getAttribute('filter');\n }\n\n set filter(value) {\n if (!value || value === '') {\n this.removeAttribute('filter');\n for (const el of this.querySelectorAll('local-service')) {\n el.removeAttribute('local-services-visible');\n }\n } else {\n this.setAttribute('filter', value);\n for (const el of this.querySelectorAll('local-service')) {\n if (!el.name) continue;\n if (el.name.includes(value)) {\n el.setAttribute('local-services-visible', 'visible');\n } else {\n el.setAttribute('local-services-visible', 'invisible');\n }\n }\n }\n }\n});\n","import { FORM_STYLE, S } from \"./shared\";\n\ncustomElements.define('login-form', class extends HTMLElement {\n static get observedAttributes() {\n return []\n }\n\n constructor() {\n super();\n const shadow = this[S] = this.attachShadow({ mode: 'closed' });\n shadow.innerHTML = `\n \n
\n
\n \n \n
\n
\n \n \n
\n
\n \n
\n
\n `;\n }\n\n connectedCallback() {\n }\n\n attributeChangedCallback(name, oldV, newV) {\n if (oldV === newV) return;\n switch (name) {\n }\n }\n});\n","import { S, FORM_STYLE } from \"./shared\";\n\ncustomElements.define('ow-account', class extends HTMLElement {\n static get observedAttributes() {\n return ['mode', \"id\", \"name\", 'email', \"facebook-id\"]\n }\n\n constructor() {\n super();\n const shadow = this[S] = this.attachShadow({ mode: 'closed' });\n shadow.innerHTML = `\n \n
\n \n \n
\n Nie masz konta? Utwórz nowe\n
\n
\n Masz konta? Zaloguj się\n
\n
\n
\n
\n \n
\n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n
\n `;\n shadow.querySelector('#switch-login > a').addEventListener('click', ev => {\n ev.stopPropagation();\n ev.preventDefault();\n this.mode = 'login';\n });\n shadow.querySelector('#switch-register > a').addEventListener('click', ev => {\n ev.stopPropagation();\n ev.preventDefault();\n this.mode = 'register';\n });\n }\n\n connectedCallback() {\n if (this.mode === '') this.mode = 'login';\n }\n\n attributeChangedCallback(name, oldV, newV) {\n if (oldV === newV) return;\n switch (name) {\n case 'mode': {\n this.mode = newV;\n break;\n }\n case 'id': {\n this.id = newV;\n break;\n }\n case 'name': {\n this.name = newV;\n break;\n }\n case 'email': {\n this.email = newV;\n break;\n }\n case 'facebook-id': {\n this.facebook_id = newV;\n break;\n }\n }\n }\n\n get mode() {\n return this.getAttribute('mode') || '';\n }\n\n set mode(value) {\n value = ['login', 'register', 'display'].includes(value) ? value : 'login';\n this.setAttribute('mode', value);\n }\n\n get name() {\n return this.getAttribute('name') || '';\n }\n\n set name(v) {\n this.setAttribute('name', v);\n this[S].querySelector('#display #name').value = v;\n }\n\n get email() {\n return this.getAttribute('email') || '';\n }\n\n set email(v) {\n this.setAttribute('email', v);\n this[S].querySelector('#display #email').value = v;\n }\n\n get facebook_id() {\n return this.getAttribute('facebook-id');\n }\n\n set facebook_id(v) {\n this.setAttribute('facebook-id', v);\n this[S].querySelector('#display #facebook_id').value = v;\n }\n});\n","import { S } from \"./shared\";\n\ncustomElements.define('ow-nav', class extends HTMLElement {\n constructor() {\n super();\n const shadow = this[S] = this.attachShadow({ mode: 'closed' });\n shadow.innerHTML = `\n \n
\n \n
\n `;\n }\n});\n","import { S } from \"./shared\";\n\ncustomElements.define('ow-path', class extends HTMLElement {\n static get observedAttributes() {\n return ['selected', 'path'];\n }\n\n constructor() {\n super();\n const shadow = this[S] = this.attachShadow({ mode: 'closed' });\n shadow.innerHTML = `\n \n \n `;\n }\n\n connectedCallback() {\n this.selected = this.getAttribute('selected');\n }\n\n attributeChangedCallback(name, oldV, newV) {\n if (oldV === newV) return;\n switch (name) {\n case 'selected':\n return this.selected = newV;\n case 'path':\n return this.path = newV;\n }\n }\n\n get selected() {\n return this.getAttribute('selected') === 'selected';\n }\n\n set selected(value) {\n if (value === 'selected') this.setAttribute('selected', 'selected');\n else this.removeAttribute('selected');\n }\n\n get path() {\n return this.getAttribute('path') || ''\n }\n\n set path(value) {\n if (!value || value === '') {\n this.removeAttribute('path');\n return;\n }\n this.setAttribute('path', value);\n this[S].querySelector('a').setAttribute('href', value);\n }\n});\n","import { S } from \"../shared\";\n\ncustomElements.define('price-view', class extends HTMLElement {\n static get observedAttributes() {\n return ['value', 'currency']\n }\n\n constructor() {\n super();\n const shadow = this[S] = this.attachShadow({ mode: 'closed' });\n shadow.innerHTML = `\n \n \n `;\n }\n\n connectedCallback() {\n this[S].querySelector('#price').textContent = this.formatted;\n }\n\n attributeChangedCallback(name, oldV, newV) {\n if (oldV === newV) return;\n switch (name) {\n case 'price': {\n this.value = newV;\n break;\n }\n }\n }\n\n get formatted() {\n let v = this.value;\n let major = Math.ceil(v / 100);\n let minor = v % 100;\n let formatted = `${ major },${ minor < 10 ? `0${ minor }` : minor }`;\n return `${ formatted }${ this.currency }`\n }\n\n get value() {\n const n = parseInt(this.getAttribute('value'));\n return isNaN(n) ? 0 : n;\n }\n\n set value(v) {\n this.setAttribute('value', v);\n this[S].querySelector('#price').textContent = this.formatted;\n }\n\n get currency() {\n return this.getAttribute('currency') || 'PLN';\n }\n});\n","import { S, FORM_STYLE } from \"../shared\";\n\ncustomElements.define('price-input', class extends HTMLElement {\n static get observedAttributes() {\n return ['value', 'currency', 'required', 'name']\n }\n\n constructor() {\n super();\n const shadow = this[S] = this.attachShadow({ mode: 'closed' });\n shadow.innerHTML = `\n \n
\n \n \n
\n `;\n }\n\n connectedCallback() {\n this[S].querySelector('#currency').textContent = this.currency;\n // this[S].querySelector('#price').textContent = this.formatted;\n }\n\n attributeChangedCallback(name, oldV, newV) {\n if (oldV === newV) return;\n const price = this[S].querySelector('#price');\n switch (name) {\n case 'price': {\n this.value = newV;\n break;\n }\n case 'currency': {\n this.currency = newV;\n break;\n }\n case 'required': {\n newV\n ? price.setAttribute('required', 'required')\n : price.removeAttribute('required');\n break;\n }\n case 'readonly': {\n newV\n ? price.setAttribute('readonly', 'readonly')\n : price.removeAttribute('readonly');\n break;\n }\n case 'name': {\n break;\n }\n }\n }\n\n get value() {\n return this[S].querySelector('#price').value * 100;\n }\n\n set value(v) {\n this.setAttribute('value', v);\n this[S].querySelector('#price').value = v;\n }\n\n get currency() {\n return this.getAttribute('currency') || 'PLN';\n }\n\n set currency(value) {\n this.setAttribute('currency', value);\n this[S].querySelector('#currency').textContent = this.currency;\n }\n\n reportValidity() {\n return this[S].querySelector('input').reportValidity();\n }\n\n get name() {\n return this.getAttribute('name');\n }\n\n set name(value) {\n this.setAttribute('name', value);\n }\n});\n","import { FORM_STYLE, S, PseudoForm } from \"../shared\";\n\ncustomElements.define('register-basic-form', class extends PseudoForm {\n constructor() {\n super();\n\n const shadow = this[S] = this.attachShadow({ mode: \"closed\" });\n\n shadow.innerHTML = `\n \n
\n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n \n
\n `;\n\n const form = shadow.querySelector('form');\n form.addEventListener('submit', ev => {\n ev.preventDefault();\n ev.stopPropagation();\n this.dispatchEvent(new CustomEvent('form:next', { bubbles: true, composed: true, detail: form }));\n })\n }\n});\n","import { S, FORM_STYLE, PseudoForm } from \"../shared\";\n\ncustomElements.define('register-item-form-row', class extends PseudoForm {\n static get observedAttributes() {\n return ['idx', 'name']\n }\n\n constructor() {\n super();\n this[S] = this.attachShadow({ mode: 'closed' });\n\n this.addEventListener('item:removed', () => {\n this.setAttribute('removed', 'removed');\n const parent = this.parentElement;\n this.remove();\n parent.dispatchEvent(new CustomEvent('item:removed', { bubbles: true, composed: true }));\n });\n }\n\n connectedCallback() {\n const idx = this.getAttribute('idx');\n this[S].innerHTML = `\n \n
\n
\n \n \n
\n
\n \n \n \n
\n
\n
\n `;\n this[S].querySelector('form').addEventListener('submit', ev => {\n ev.preventDefault();\n ev.stopPropagation();\n this.reportValidity();\n });\n this[S].querySelector('.remove').addEventListener('click', ev => {\n ev.preventDefault();\n ev.stopPropagation();\n\n this.dispatchEvent(new CustomEvent('item:removed', { bubbles: true, composed: false }));\n });\n }\n\n attributeChangedCallback(name, oldV, newV) {\n if (oldV === newV) return;\n switch (name) {\n case 'idx': {\n this.updateNames();\n break;\n }\n }\n }\n\n\n get inputs() {\n return [\n this[S].querySelector('.item-name').cloneNode(true),\n this[S].querySelector('.item-price').cloneNode(true),\n ];\n }\n\n updateNames() {\n const idx = this.getAttribute('idx');\n for (const el of this[S].querySelectorAll('.field')) {\n const id = el.id;\n el.querySelector('input, price-input').setAttribute('name', `items[${ idx }][${ id }]`);\n }\n }\n\n get idx() {\n return this.getAttribute('idx');\n }\n\n set idx(idx) {\n this.setAttribute('idx', idx);\n }\n\n reportValidity() {\n return super.reportValidity() && this[S].querySelector('price-input').reportValidity();\n }\n});\n","import { FORM_STYLE, S, PseudoForm } from \"../shared\";\n\nimport \"./register-item-form-row\"\n\nconst updateItems = (form) => {\n let idx = 0;\n for (const el of form.querySelectorAll('register-item-form-row')) {\n el.idx = idx++;\n }\n return idx;\n}\n\ncustomElements.define('register-items-form', class extends PseudoForm {\n static get observedAttributes() {\n return []\n }\n\n constructor() {\n super();\n const shadow = this[S] = this.attachShadow({ mode: 'closed' });\n shadow.innerHTML = `\n \n
\n
\n \n
\n
\n \n
\n \n
\n `;\n this.addEventListener('item:removed', ev => {\n ev.stopPropagation();\n updateItems(this)\n });\n this.addEventListener('form:next', ev => {\n for (const el of this.querySelectorAll('item-form-row')) {\n if (!el.reportValidity()) {\n ev.stopPropagation();\n ev.preventDefault();\n }\n }\n });\n shadow.querySelector('#add-item').addEventListener('click', ev => {\n ev.stopPropagation();\n ev.preventDefault();\n this.appendChild(document.createElement('register-item-form-row'));\n updateItems(this)\n });\n }\n\n get inputs() {\n return [...this.querySelectorAll(\"register-item-form-row\")].map(form => form.inputs)\n }\n});\n","import { FORM_STYLE, S, PseudoForm } from \"../shared\";\n\ncustomElements.define('register-company-form', class extends PseudoForm {\n constructor() {\n super();\n\n const shadow = this[S] = this.attachShadow({mode: \"closed\"});\n\n shadow.innerHTML = `\n \n
\n
\n \n
\n
\n \n \n
\n \n
\n `;\n }\n})\n","import { FORM_STYLE, S, PseudoForm } from \"../shared\";\n\ncustomElements.define('register-submit-form', class extends PseudoForm {\n constructor() {\n super();\n\n const shadow = this[S] = this.attachShadow({ mode: \"closed\" });\n\n shadow.innerHTML = `\n \n
\n
\n \n \n \n \n \n
\n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n \n
\n
\n \n
\n \n \n
\n
\n `;\n }\n\n updateField(name, value) {\n this[S].querySelector(`[id=\"hidden-${ name }\"]`).value = value;\n this[S].querySelector(`[id=\"preview-${ name }\"]`).value = value;\n }\n\n setItems(items) {\n const host = this[S].querySelector('#items');\n host.innerHTML = ``;\n for (const row of items) {\n const el = host.appendChild(document.createElement('div'));\n const [name, price] = row;\n\n name.setAttribute('readonly', 'readonly');\n el.appendChild(name);\n\n el.appendChild(document.createElement('price-view')).value = price.value;\n price.setAttribute('readonly', 'readonly');\n price.setAttribute('type', 'hidden');\n el.appendChild(price);\n }\n }\n\n set accountType(v) {\n this[S].querySelector('#account_type').value = v;\n }\n});\n","customElements.define('register-user-type', class extends HTMLElement {\n constructor() {\n super();\n\n const shadow = this.attachShadow({ mode: \"closed\" });\n\n shadow.innerHTML = `\n \n
\n \n
\n `;\n\n const user = shadow.querySelector('#user');\n user.addEventListener('click', ev => {\n ev.preventDefault();\n ev.stopPropagation();\n this.dispatchEvent(new CustomEvent('account:type:user', { bubbles: true, composed: true }));\n });\n const service = shadow.querySelector('#local-service');\n service.addEventListener('click', ev => {\n ev.preventDefault();\n ev.stopPropagation();\n this.dispatchEvent(new CustomEvent('account:type:local-service', { bubbles: true, composed: true }));\n });\n }\n});\n","import { S, FORM_STYLE } from \"../shared\";\n\ncustomElements.define('register-user-form', class extends HTMLElement {\n static get observedAttributes() {\n return ['mode']\n }\n\n constructor() {\n super();\n\n const shadow = this[S] = this.attachShadow({ mode: \"closed\" });\n\n shadow.innerHTML = `\n \n
\n
\n \n \n \n \n
\n \n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n
\n \n
\n
\n
\n
\n \n \n \n
\n
\n `;\n\n const form = shadow.querySelector('form');\n\n shadow.querySelector('#fb-icon').addEventListener('click', ev => {\n ev.stopPropagation();\n ev.preventDefault();\n this.mode = 'facebook';\n FB.login((res) => {\n if (res.status === 'connected') {\n FB.api(\"/me?fields=id,name,email\", ({ id, name, email, ...rest }) => {\n console.log(id, name, email, rest);\n form.querySelector('#email').value = email;\n form.querySelector('#login').value = name;\n form.querySelector('#password').value = crypto.randomUUID();\n form.querySelector('#facebook_id').value = id;\n form.submit();\n });\n }\n }, { scope: 'public_profile,email', return_scopes: true });\n });\n\n shadow.querySelector('#email-icon').addEventListener('click', ev => {\n ev.stopPropagation();\n ev.preventDefault();\n\n this.mode = 'email';\n });\n }\n\n connectedCallback() {\n this.mode = '';\n }\n\n attributeChangedCallback(name, oldV, newV) {\n if (oldV === newV) return;\n switch (name) {\n case 'mode': {\n if (newV !== 'email' && newV !== 'facebook' && newV !== '')\n return;\n this.mode = newV;\n break;\n }\n }\n }\n\n get mode() {\n return this.getAttribute('mode') || ''\n }\n\n set mode(v) {\n this.setAttribute('mode', v);\n }\n});\n","import { S, FORM_STYLE } from \"./shared\";\n\nimport \"./register-form/register-basic-form\";\nimport \"./register-form/register-item-form-row.js\";\nimport \"./register-form/register-items-form.js\";\nimport \"./register-form/register-company-form\";\nimport \"./register-form/register-submit-form\";\nimport \"./register-form/register-user-type\";\nimport \"./register-form/register-user-form\";\n\nconst copyForm = (form, finalForm) => {\n form.reportValidity();\n\n for (const el of form.elements) {\n if (el.name === '') continue;\n if (!el.reportValidity()) {\n return false;\n }\n }\n const inputs = form.inputs;\n if (inputs)\n finalForm.setItems(inputs);\n else\n for (const el of form.elements) {\n if (el.name === '') continue;\n finalForm.updateField(el.name, el.value);\n }\n return true;\n};\n\ncustomElements.define('register-form', class extends HTMLElement {\n static get observedAttributes() {\n return ['step']\n }\n\n constructor() {\n super();\n const shadow = this[S] = this.attachShadow({ mode: 'closed' });\n shadow.innerHTML = `\n \n
\n
\n
\n \n \n \n \n \n \n
\n `;\n\n const finalForm = shadow.querySelector('#step-4');\n this[S].addEventListener('account:type:user', ev => {\n ev.stopPropagation();\n finalForm.accountType = 'User';\n this.step = 40;\n });\n this[S].addEventListener('account:type:local-service', ev => {\n ev.stopPropagation();\n finalForm.accountType = 'Business';\n this.step = 1;\n });\n this[S].addEventListener('form:next', ev => {\n ev.stopPropagation();\n const form = shadow.querySelector(`#step-${ this.step }`);\n if (copyForm(form, finalForm)) {\n this.step = this.step + 1;\n }\n });\n this[S].addEventListener('form:prev', ev => {\n ev.stopPropagation();\n this.step = this.step - 1;\n });\n {\n finalForm.addEventListener('submit', ev => {\n ev.preventDefault();\n ev.stopPropagation();\n });\n }\n }\n\n connectedCallback() {\n this.step = 0;\n }\n\n attributeChangedCallback(name, oldV, newV) {\n if (oldV === newV) return;\n switch (name) {\n }\n }\n\n get step() {\n const step = parseInt(this.getAttribute('step'));\n return isNaN(step) ? 1 : step;\n }\n\n set step(n) {\n if (n < 0) return;\n this.setAttribute('step', n);\n }\n});\n","import \"./form-navigation.js\";\nimport \"./local-service.js\";\nimport \"./local-service-item.js\";\nimport \"./local-services.js\";\nimport \"./login-form.js\";\nimport \"./ow-account.js\";\nimport \"./ow-nav.js\";\nimport \"./ow-path.js\";\nimport \"./price/price-view\";\nimport \"./price/price-input\";\nimport \"./register-form.js\";\nimport { fireFbReady } from \"./shared.js\";\n\nif (!document.querySelector('#facebook-jssdk')) {\n window.fbAsyncInit = () => {\n FB.init({\n appId: '1293538251053124',\n cookie: true,\n xfbml: true,\n version: 'v14.0'\n });\n FB.AppEvents.logPageView();\n fireFbReady();\n };\n\n const js = document.createElement('script');\n js.id = 'facebook-jssdk';\n js.src = \"https://connect.facebook.net/en_US/sdk.js\";\n document.head.appendChild(js);\n}\n"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/client/src/app.js b/client/src/app.js index 084fc85..7e41fb9 100644 --- a/client/src/app.js +++ b/client/src/app.js @@ -4,29 +4,27 @@ import "./local-service-item.js"; import "./local-services.js"; import "./login-form.js"; import "./ow-account.js"; -import "./ow-nav.js"; -import "./ow-path.js"; +import "./nav/ow-nav.js"; +import "./nav/ow-path.js"; import "./price/price-view"; import "./price/price-input"; import "./register-form.js"; import { fireFbReady } from "./shared.js"; -window.fbAsyncInit = () => { - FB.init({ - appId : '1293538251053124', - cookie : true, - xfbml : true, - version : 'v14.0' - }); - FB.AppEvents.logPageView(); - fireFbReady(); -}; +if (!document.querySelector('#facebook-jssdk')) { + window.fbAsyncInit = () => { + FB.init({ + appId: '1293538251053124', + cookie: true, + xfbml: true, + version: 'v14.0' + }); + FB.AppEvents.logPageView(); + fireFbReady(); + }; -{ - if (!document.querySelector('#facebook-jssdk')) { - const js = document.createElement('script'); - js.id = 'facebook-jssdk'; - js.src = "https://connect.facebook.net/en_US/sdk.js"; - document.head.appendChild(js); - } + const js = document.createElement('script'); + js.id = 'facebook-jssdk'; + js.src = "https://connect.facebook.net/en_US/sdk.js"; + document.head.appendChild(js); } diff --git a/client/src/form-navigation.js b/client/src/form-navigation.js index c292c38..a6ace0c 100644 --- a/client/src/form-navigation.js +++ b/client/src/form-navigation.js @@ -22,7 +22,7 @@ customElements.define('form-navigation', class extends HTMLElement { display: none !important; } -
+
diff --git a/client/src/ow-nav.js b/client/src/nav/ow-nav.js similarity index 100% rename from client/src/ow-nav.js rename to client/src/nav/ow-nav.js diff --git a/client/src/ow-path.js b/client/src/nav/ow-path.js similarity index 100% rename from client/src/ow-path.js rename to client/src/nav/ow-path.js diff --git a/client/src/ow-account.js b/client/src/ow-account.js index fe3c46a..cc1daf1 100644 --- a/client/src/ow-account.js +++ b/client/src/ow-account.js @@ -1,8 +1,8 @@ -import { S } from "./shared"; +import { S, FORM_STYLE } from "./shared"; customElements.define('ow-account', class extends HTMLElement { static get observedAttributes() { - return ['mode'] + return ['mode', "id", "name", 'email', "facebook-id"] } constructor() { @@ -12,7 +12,7 @@ customElements.define('ow-account', class extends HTMLElement { -
+ +
+
+ +
+
+ + +
+
+ + +
+
+ + +
+
`; shadow.querySelector('#switch-login > a').addEventListener('click', ev => { ev.stopPropagation(); @@ -55,21 +80,68 @@ customElements.define('ow-account', class extends HTMLElement { } connectedCallback() { - this.mode = 'login'; + if (this.mode === '') this.mode = 'login'; } attributeChangedCallback(name, oldV, newV) { if (oldV === newV) return; switch (name) { + case 'mode': { + this.mode = newV; + break; + } + case 'id': { + this.id = newV; + break; + } + case 'name': { + this.name = newV; + break; + } + case 'email': { + this.email = newV; + break; + } + case 'facebook-id': { + this.facebook_id = newV; + break; + } } } get mode() { - return this.getAttribute('mode'); + return this.getAttribute('mode') || ''; } set mode(value) { - value = value === 'login' || value === 'register' ? value : 'login'; + value = ['login', 'register', 'display'].includes(value) ? value : 'login'; this.setAttribute('mode', value); } + + get name() { + return this.getAttribute('name') || ''; + } + + set name(v) { + this.setAttribute('name', v); + this[S].querySelector('#display #name').value = v; + } + + get email() { + return this.getAttribute('email') || ''; + } + + set email(v) { + this.setAttribute('email', v); + this[S].querySelector('#display #email').value = v; + } + + get facebook_id() { + return this.getAttribute('facebook-id'); + } + + set facebook_id(v) { + this.setAttribute('facebook-id', v); + this[S].querySelector('#display #facebook_id').value = v; + } }); diff --git a/client/src/register-form.js b/client/src/register-form.js index 31690f1..59efc54 100644 --- a/client/src/register-form.js +++ b/client/src/register-form.js @@ -6,7 +6,7 @@ import "./register-form/register-items-form.js"; import "./register-form/register-company-form"; import "./register-form/register-submit-form"; import "./register-form/register-user-type"; -import "./register-form/register-oauth2"; +import "./register-form/register-user-form"; const copyForm = (form, finalForm) => { form.reportValidity(); @@ -46,7 +46,7 @@ customElements.define('register-form', class extends HTMLElement { :host([step="2"]) #step-2 { display: block; } :host([step="3"]) #step-3 { display: block; } :host([step="4"]) #step-4 { display: block; } - :host([step="1000"]) #step-1000 { display: block; } + :host([step="40"]) #step-40 { display: block; } ${ FORM_STYLE } @@ -64,34 +64,27 @@ customElements.define('register-form', class extends HTMLElement { display: none; } +
+
- - - - - - - - - - - - - - - - - + + + + + +
`; const finalForm = shadow.querySelector('#step-4'); this[S].addEventListener('account:type:user', ev => { ev.stopPropagation(); - this.step = 1000; + finalForm.accountType = 'User'; + this.step = 40; }); this[S].addEventListener('account:type:local-service', ev => { ev.stopPropagation(); + finalForm.accountType = 'Business'; this.step = 1; }); this[S].addEventListener('form:next', ev => { @@ -106,8 +99,7 @@ customElements.define('register-form', class extends HTMLElement { this.step = this.step - 1; }); { - const el = finalForm; - el.addEventListener('submit', ev => { + finalForm.addEventListener('submit', ev => { ev.preventDefault(); ev.stopPropagation(); }); diff --git a/client/src/register-form/register-basic-form.js b/client/src/register-form/register-basic-form.js index 5313a25..548cf4e 100644 --- a/client/src/register-form/register-basic-form.js +++ b/client/src/register-form/register-basic-form.js @@ -26,7 +26,7 @@ customElements.define('register-basic-form', class extends PseudoForm {
- +
`; diff --git a/client/src/register-form/register-item-form-row.js b/client/src/register-form/register-item-form-row.js index aabf666..6fdfec4 100644 --- a/client/src/register-form/register-item-form-row.js +++ b/client/src/register-form/register-item-form-row.js @@ -68,8 +68,8 @@ customElements.define('register-item-form-row', class extends PseudoForm { get inputs() { return [ - this[S].querySelector('input.item-name').cloneNode(true), - this[S].querySelector('input.item-price').cloneNode(true), + this[S].querySelector('.item-name').cloneNode(true), + this[S].querySelector('.item-price').cloneNode(true), ]; } diff --git a/client/src/register-form/register-oauth2.js b/client/src/register-form/register-oauth2.js deleted file mode 100644 index 6c7bf23..0000000 --- a/client/src/register-form/register-oauth2.js +++ /dev/null @@ -1,101 +0,0 @@ -import { runFbReady } from "../shared"; - -customElements.define('register-oauth2', class extends HTMLElement { - static get observedAttributes() { - return ['fb-connected'] - } - constructor() { - super(); - - const shadow = this.attachShadow({ mode: "closed" }); - shadow.innerHTML = ` - - - -
-Rejestracja adresem e-mail -
- - -
-
- - -
-
- - -
-
- -
-
- - - `; - } - - connectedCallback() { - runFbReady(() => { - FB.getLoginStatus(({ status }) => { - if (status !== 'connected') - FB.login(); - else - this.setAttribute('fb-connected', '1'); - }); - }); - } -}); diff --git a/client/src/register-form/register-submit-form.js b/client/src/register-form/register-submit-form.js index cd954a5..61f3231 100644 --- a/client/src/register-form/register-submit-form.js +++ b/client/src/register-form/register-submit-form.js @@ -40,6 +40,7 @@ customElements.define('register-submit-form', class extends PseudoForm { +
@@ -72,4 +73,8 @@ customElements.define('register-submit-form', class extends PseudoForm { el.appendChild(price); } } + + set accountType(v) { + this[S].querySelector('#account_type').value = v; + } }); diff --git a/client/src/register-form/register-user-form.js b/client/src/register-form/register-user-form.js new file mode 100644 index 0000000..d11711f --- /dev/null +++ b/client/src/register-form/register-user-form.js @@ -0,0 +1,127 @@ +import { S, FORM_STYLE } from "../shared"; + +customElements.define('register-user-form', class extends HTMLElement { + static get observedAttributes() { + return ['mode'] + } + + constructor() { + super(); + + const shadow = this[S] = this.attachShadow({ mode: "closed" }); + + shadow.innerHTML = ` + +
+
+ + + + +
+ +
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
+
+ + + +
+
+ `; + + const form = shadow.querySelector('form'); + + shadow.querySelector('#fb-icon').addEventListener('click', ev => { + ev.stopPropagation(); + ev.preventDefault(); + this.mode = 'facebook'; + FB.login((res) => { + if (res.status === 'connected') { + FB.api("/me?fields=id,name,email", ({ id, name, email, ...rest }) => { + console.log(id, name, email, rest); + form.querySelector('#email').value = email; + form.querySelector('#login').value = name; + form.querySelector('#password').value = crypto.randomUUID(); + form.querySelector('#facebook_id').value = id; + form.submit(); + }); + } + }, { scope: 'public_profile,email', return_scopes: true }); + }); + + shadow.querySelector('#email-icon').addEventListener('click', ev => { + ev.stopPropagation(); + ev.preventDefault(); + + this.mode = 'email'; + }); + } + + connectedCallback() { + this.mode = ''; + } + + attributeChangedCallback(name, oldV, newV) { + if (oldV === newV) return; + switch (name) { + case 'mode': { + if (newV !== 'email' && newV !== 'facebook' && newV !== '') + return; + this.mode = newV; + break; + } + } + } + + get mode() { + return this.getAttribute('mode') || '' + } + + set mode(v) { + this.setAttribute('mode', v); + } +}); diff --git a/client/src/shared.js b/client/src/shared.js index a032362..7902419 100644 --- a/client/src/shared.js +++ b/client/src/shared.js @@ -4,9 +4,10 @@ export const FORM_STYLE = ` form { display: block; } -form.inline { - display: flex; - justify-content: space-between; +form legend { + margin: 16px 0; + font-weight: bold; + font-size: 20px; } form > div { display: block; diff --git a/migrations/20220706095417_add_facebook_id.sql b/migrations/20220706095417_add_facebook_id.sql new file mode 100644 index 0000000..e9179ea --- /dev/null +++ b/migrations/20220706095417_add_facebook_id.sql @@ -0,0 +1 @@ +ALTER TABLE accounts ADD COLUMN facebook_id TEXT DEFAULT NULL; diff --git a/migrations/20220706130049_add_account_type.sql b/migrations/20220706130049_add_account_type.sql new file mode 100644 index 0000000..03d63ee --- /dev/null +++ b/migrations/20220706130049_add_account_type.sql @@ -0,0 +1,8 @@ +CREATE TYPE "AccountType" AS ENUM ( + 'User', + 'Business', + 'Admin' + ); + +ALTER TABLE accounts + ADD COLUMN account_type "AccountType" default 'User'; diff --git a/src/main.rs b/src/main.rs index 8c1f75a..7d26409 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,14 +1,17 @@ #![feature(drain_filter)] -use actix_web::{App, HttpServer, web::Data}; + +use crate::routes::render_index; +use actix_identity::{CookieIdentityPolicy, IdentityService}; +use actix_web::{web, web::Data, App, HttpResponse, HttpServer}; mod auth; mod model; mod routes; +mod utils; -#[actix_web::main] // or #[tokio::main] +#[actix_web::main] async fn main() -> std::io::Result<()> { - use actix_web::middleware::Logger; - use tracing::{Level}; + use tracing::Level; use tracing_subscriber::FmtSubscriber; let subscriber = FmtSubscriber::builder() .with_max_level(Level::DEBUG) @@ -23,10 +26,17 @@ async fn main() -> std::io::Result<()> { .unwrap(); HttpServer::new(move || { + let policy = CookieIdentityPolicy::new(&[0; 32]) + .name("auth-cookie") + .secure(false); + App::new() - .wrap(Logger::default()) + .wrap(actix_web::middleware::Compress::default()) + .wrap(actix_web::middleware::Logger::default()) + .wrap(IdentityService::new(policy)) .app_data(Data::new(pool.clone())) .configure(routes::configure) + .default_service(web::to(render_index)) }) .bind(("0.0.0.0", 8080))? .run() diff --git a/src/model/db.rs b/src/model/db.rs index a04a27c..437a66c 100644 --- a/src/model/db.rs +++ b/src/model/db.rs @@ -4,12 +4,21 @@ use sqlx::{FromRow, Type}; use std::collections::HashMap; use uuid::Uuid; +#[derive(Debug, PartialOrd, PartialEq, Serialize, Deserialize, Type)] +pub enum AccountType { + User, + Business, + Admin, +} + #[derive(Debug, Serialize, Deserialize, FromRow)] pub struct Account { pub id: i32, pub login: String, pub email: String, pub pass: String, + pub facebook_id: Option, + pub account_type: AccountType, } #[derive(Debug, Serialize, Deserialize, Type)] diff --git a/src/model/view.rs b/src/model/view.rs index 5903afb..75bcb23 100644 --- a/src/model/view.rs +++ b/src/model/view.rs @@ -1,6 +1,41 @@ use crate::model::db; use serde::{Deserialize, Serialize}; +#[derive(Debug)] +pub enum Page { + LocalServices, + News, + Account, + Register, + Login, +} + +impl Page { + pub fn select_index(&self) -> &str { + if matches!(self, Page::LocalServices) { + "selected" + } else { + "" + } + } + + pub fn select_news(&self) -> &str { + if matches!(self, Page::News) { + "selected" + } else { + "" + } + } + + pub fn select_account(&self) -> &str { + if matches!(self, Page::Account) { + "selected" + } else { + "" + } + } +} + #[derive(Debug, Serialize, Deserialize)] pub struct LocalService { pub id: i32, diff --git a/src/routes/mod.rs b/src/routes/mod.rs index 8313d38..375481a 100644 --- a/src/routes/mod.rs +++ b/src/routes/mod.rs @@ -2,6 +2,8 @@ use actix_web::web::ServiceConfig; mod unrestricted; +pub use unrestricted::render_index; + pub fn configure(config: &mut ServiceConfig) { unrestricted::configure(config); } diff --git a/src/routes/unrestricted.rs b/src/routes/unrestricted.rs index 90bac5e..5a742cc 100644 --- a/src/routes/unrestricted.rs +++ b/src/routes/unrestricted.rs @@ -1,17 +1,43 @@ +use crate::model::db; +use crate::model::db::AccountType; +use crate::model::view::Page; +use crate::utils; use actix_files::Files; +use actix_identity::Identity; use actix_web::web::{Data, ServiceConfig}; use actix_web::*; use askama::Template; +use serde::Deserialize; #[derive(Template)] #[template(path = "index.html")] pub struct IndexTemplate { - pub services: Vec, + services: Vec, + account: Option, + error: Option, + page: Page, +} + +pub async fn render_index() -> HttpResponse { + HttpResponse::NotFound().body( + IndexTemplate { + services: vec![], + account: None, + error: None, + page: Page::LocalServices, + } + .render() + .unwrap(), + ) } #[get("/")] -pub async fn index(db: Data) -> HttpResponse { +pub async fn index(db: Data, id: Identity) -> HttpResponse { let pool = db.into_inner(); + let record = match id.identity() { + Some(id) => utils::user_by_id(id, &pool).await, + _ => None, + }; let (services, mut items) = { use crate::model::db::{LocalService, LocalServiceItem}; let services: Vec = sqlx::query_as( @@ -62,17 +88,194 @@ FROM local_service_items .collect() }; - let body = IndexTemplate { services }.render().unwrap(); + let body = IndexTemplate { + services, + account: record, + error: None, + page: Page::LocalServices, + } + .render() + .unwrap(); HttpResponse::Ok().body(body) } #[derive(Template)] #[template(path = "account.html")] -struct AccountTemplate; +struct AccountTemplate { + account: Option, + error: Option, + page: Page, +} #[get("/account")] -async fn account() -> HttpResponse { - HttpResponse::Ok().body(AccountTemplate.render().unwrap()) +async fn account_page(id: Identity, db: Data) -> HttpResponse { + let pool = db.into_inner(); + let record = match id.identity() { + Some(id) => utils::user_by_id(id, &pool).await, + _ => None, + }; + HttpResponse::Ok().body( + AccountTemplate { + account: record, + error: None, + page: Page::Account, + } + .render() + .unwrap(), + ) +} + +#[derive(Debug, Deserialize)] +struct RegisterForm { + email: String, + login: String, + password: String, + facebook_id: Option, + account_type: db::AccountType, +} + +#[post("/register")] +async fn register( + form: web::Form, + db: Data, + id: Identity, +) -> HttpResponse { + let form = form.into_inner(); + let pool = db.into_inner(); + if form.account_type == AccountType::Admin { + return HttpResponse::BadRequest().body("Breach attempt detected!"); + } + + let pass = match utils::encrypt(&form.password) { + Ok(pass) => pass, + Err(e) => { + tracing::error!("{:?}", e); + return HttpResponse::BadRequest().body( + AccountTemplate { + account: None, + error: Some("Zapisanie hasła nie powiodło się".into()), + page: Page::Register, + } + .render() + .unwrap(), + ); + } + }; + + let res: sqlx::Result = sqlx::query_as( + r#" +INSERT INTO accounts (login, email, pass, facebook_id, account_type) +VALUES ($1, $2, $3, $4) +RETURNING id, login, email, pass, facebook_id, account_type + "#, + ) + .bind(form.login) + .bind(form.email) + .bind(pass) + .bind(form.facebook_id) + .fetch_one(&*pool) + .await; + match res { + Ok(res) => { + id.remember(format!("{}", res.id)); + HttpResponse::Ok().body( + AccountTemplate { + account: Some(res), + error: None, + page: Page::Register, + } + .render() + .unwrap(), + ) + } + Err(e) => { + eprintln!("{e}"); + HttpResponse::BadRequest().body( + AccountTemplate { + account: None, + error: Some("Problem z utworzeniem konta".into()), + page: Page::Register, + } + .render() + .unwrap(), + ) + } + } +} + +#[post("/logout")] +async fn logout(id: Identity) -> HttpResponse { + id.forget(); + HttpResponse::SeeOther() + .append_header(("Location", "/")) + .body( + IndexTemplate { + services: vec![], + account: None, + error: None, + page: Page::LocalServices, + } + .render() + .unwrap(), + ) +} + +#[derive(Debug, Deserialize)] +struct LoginForm { + email: String, + password: String, +} + +#[post("/login")] +async fn login(form: web::Form, db: Data, id: Identity) -> HttpResponse { + let pool = db.into_inner(); + let form = form.into_inner(); + let record: db::Account = match sqlx::query_as( + r#" +SELECT id, login, email, pass, facebook_id, account_type +FROM accounts +WHERE email = $1 + "#, + ) + .bind(form.email) + .fetch_one(&*pool) + .await + { + Ok(record) => record, + Err(e) => { + tracing::error!("{e}"); + return HttpResponse::Ok().body( + AccountTemplate { + account: None, + error: Some("Nie znaleziono konta".into()), + page: Page::Login, + } + .render() + .unwrap(), + ); + } + }; + if utils::validate(&form.password, &record.pass).is_err() { + return HttpResponse::BadRequest().body( + AccountTemplate { + account: None, + error: Some("Hasło i/lub adres e-mail są nieprawidłowe".into()), + page: Page::Login, + } + .render() + .unwrap(), + ); + } + id.remember(format!("{}", record.id)); + HttpResponse::Ok().body( + AccountTemplate { + account: Some(record), + error: None, + page: Page::Login, + } + .render() + .unwrap(), + ) } pub fn configure(config: &mut ServiceConfig) { @@ -86,5 +289,8 @@ pub fn configure(config: &mut ServiceConfig) { .show_files_listing(), ) .service(index) - .service(account); + .service(account_page) + .service(register) + .service(logout) + .service(login); } diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..9e83643 --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,52 @@ +use crate::model::db; +use argon2::{Algorithm, Argon2, Params, Version}; +use password_hash::{PasswordHash, PasswordHasher, PasswordVerifier, SaltString}; + +pub fn encrypt(pass: &str) -> password_hash::Result { + tracing::debug!("Hashing password {:?}", pass); + Ok( + Argon2::new(Algorithm::Argon2id, Version::V0x13, Params::default()) + .hash_password(pass.as_bytes(), &SaltString::generate(rand::rngs::OsRng))? + .to_string(), + ) +} + +pub fn validate(pass: &str, pass_hash: &str) -> password_hash::Result<()> { + tracing::debug!("Validating password {:?} {:?}", pass, pass_hash); + + Argon2::default().verify_password( + pass.as_bytes(), + &PasswordHash::new(pass_hash).expect("Invalid hashed password"), + ) +} + +pub async fn user_by_id(id: String, pool: &sqlx::PgPool) -> Option { + match sqlx::query_as( + r#" +SELECT id, login, email, pass, facebook_id, account_type +FROM accounts +WHERE id = $1 :: INT + "#, + ) + .bind(id) + .fetch_optional(pool) + .await + { + Ok(res) => res, + Err(e) => { + tracing::error!("{e}"); + None + } + } +} + +#[cfg(test)] +mod tests { + use crate::utils::{encrypt, validate}; + + #[test] + fn check_pass() { + let pass = "foobar"; + validate(pass, &encrypt(pass).unwrap()).unwrap(); + } +}