Skip to content

Commit

Permalink
telegram-reg (#37)
Browse files Browse the repository at this point in the history
* telegram-reg initial

* fmt

* features flags

* job update
  • Loading branch information
tikitko authored Nov 15, 2023
1 parent 22f9779 commit 097cb4b
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 56 deletions.
13 changes: 13 additions & 0 deletions .github/workflows/builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ jobs:
env:
YANDEX_CLIENT_ID: ""
API_URL: ""
TELEGRAM_BOT_LOGIN: ""
TITLE: ""
DESCRIPTION: ""
KEYWORDS: ""
Expand All @@ -30,8 +31,20 @@ jobs:
is_wasm: false
- features: "server"
is_wasm: false
- features: "server,yandex"
is_wasm: false
- features: "server,telegram"
is_wasm: false
- features: "server,yandex,telegram"
is_wasm: false
- features: "client"
is_wasm: true
- features: "client,yandex"
is_wasm: true
- features: "client,telegram"
is_wasm: true
- features: "client,yandex,telegram"
is_wasm: true
- features: "client, hydration"
is_wasm: true
steps:
Expand Down
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ default = ["client"]
server = ["yew/ssr"]
client = ["yew/csr", "yew-hooks", "wasm-bindgen-futures", "wasm-bindgen", "wasm-cookies", "wasm-logger", "web-sys", "gloo", "gloo-net"]
hydration = ["client", "yew/hydration"]
yandex = []
telegram = []


[[bin]]
Expand Down
21 changes: 21 additions & 0 deletions index.css
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,27 @@
height: 56px;
}

.telegramAuth {
background-color: #4c92c7;
border-radius: 5px;
background-position: revert;
background-size: cover;
background-size: 70%;
background-position-x: 98%;
background-position-y: 40%;
background-repeat: no-repeat;
background-image: url(data:image/svg+xml,%3Csvg%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20width%3D%2224%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22m1.95617055%2011.392196c5.77764656-2.42328736%209.63031585-4.02086673%2011.55800785-4.79273807%205.5039525-2.20384954%206.6476266-2.5866818%207.3930574-2.59932314.1639507-.00278035.5305319.0363352.7679878.22182361.2005031.15662277.2556695.36819788.2820684.51669348.026399.1484956.0592719.48677234.0331404.75109194-.2982611%203.0169019-1.5888322%2010.33812718-2.2454015%2013.71710898-.2778191%201.4297738-.8288514%201.7357846-1.3584441%201.7826999-1.1509274.1019576-2.0208916-.5588425-3.1356211-1.2622918-1.7443316-1.1007592-2.3854935-1.3972358-4.0786694-2.4713734-1.95675765-1.2413519-.8891962-1.8911034.2259543-3.0061212.2918402-.2918054%205.3989024-4.83750096%205.497052-5.24030969.0122753-.05037796-.1557336-.55407742-.2716182-.65323489-.1158847-.09915747-.2869204-.06524947-.4103446-.03828214-.17495.03822537-2.9615423%201.81132342-8.35977698%205.31929412-.79096496.5228681-1.50739646.7776269-2.1492945.7642766-.70764107-.0147176-2.06885864-.3851791-3.08078398-.7018404-1.24116762-.388398-1.69932554-.5713149-1.61342745-1.2309348.04474105-.3435709.36011227-.7024173.94611366-1.0765391z%22%20fill%3D%22%23fff%22%20fill-rule%3D%22evenodd%22%2F%3E%3C%2Fsvg%3E);
}

.telegramAuth .telegramAuthContainer {
width: 234px;
padding-top: 30px;
padding-bottom: 30px;
line-height: 0;
margin-right: auto;
margin-left: 30px;
}

article .article-img {
position: relative!important;
left: -12px!important;
Expand Down
186 changes: 132 additions & 54 deletions src/components/login_modal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
use gloo::events::EventListener;
#[cfg(feature = "client")]
use gloo::utils::document;
#[cfg(feature = "client")]
#[cfg(all(feature = "client", feature = "yandex"))]
use gloo::utils::window;
#[cfg(feature = "client")]
#[cfg(all(feature = "client", any(feature = "yandex", feature = "telegram")))]
use wasm_bindgen::JsCast;
#[cfg(all(feature = "client", any(feature = "yandex", feature = "telegram")))]
use web_sys::CustomEvent;
#[cfg(feature = "client")]
use web_sys::{CustomEvent, Element, HtmlElement, HtmlInputElement};
use web_sys::{Element, HtmlElement, HtmlInputElement};
use yew::prelude::*;

use crate::components::delayed_component::*;
Expand Down Expand Up @@ -48,9 +50,14 @@ pub fn login_modal(props: &LoginModalProps) -> Html {
InProgressStateType::Default(login_question) => {
API::<LoginAnswer>::get(login_question)
}
#[cfg(feature = "yandex")]
InProgressStateType::Yandex(login_yandex_question) => {
API::<LoginAnswer>::get(login_yandex_question)
}
#[cfg(feature = "telegram")]
InProgressStateType::Telegram(login_telegram_question) => {
API::<LoginAnswer>::get(login_telegram_question)
}
}
.await;
match login_response {
Expand Down Expand Up @@ -133,7 +140,7 @@ pub fn login_modal(props: &LoginModalProps) -> Html {
});
}

#[cfg(feature = "client")]
#[cfg(all(feature = "client", feature = "yandex"))]
{
let logged_user_context = logged_user_context.clone();
let modal_node_ref = modal_node_ref.clone();
Expand Down Expand Up @@ -176,6 +183,124 @@ pub fn login_modal(props: &LoginModalProps) -> Html {
});
}

#[cfg(all(feature = "client", feature = "telegram"))]
{
let logged_user_context = logged_user_context.clone();
let modal_node_ref = modal_node_ref.clone();
use_effect_with((), move |_| {
let modal_element = modal_node_ref.cast::<HtmlElement>().unwrap();

let data_listener = {
let logged_user_context = logged_user_context.clone();
EventListener::new(&modal_element, "telegram.auth.data", move |e| {
let e = e.dyn_ref::<CustomEvent>().unwrap();
e.prevent_default();
if let Some(login_telegram_question) = e
.detail()
.as_string()
.map(|j| serde_json::from_str::<LoginTelegramQuestion>(j.as_str()).ok())
.flatten()
{
logged_user_context.dispatch(LoggedUserState::InProgress(
InProgressStateType::Telegram(login_telegram_question),
));
} else {
logged_user_context.dispatch(LoggedUserState::Error(
"incorrect data from telegram".to_string(),
));
}
})
};
move || drop(data_listener)
});
}

#[cfg(feature = "yandex")]
let yandex_html = html! {
<>
<script id="yandexAuthScript" src="https://yastatic.net/s3/passport-sdk/autofill/v1/sdk-suggest-with-polyfills-latest.js"></script>
<DelayedComponent<()> component={ move |_| {
#[cfg(feature = "client")]
{
let script: Element = document().create_element("script").unwrap();
script.set_attribute("type", "text/javascript").unwrap();
script.set_inner_html(format!("
function yaAuthSuggestAction() {{
var modalElement = document.getElementById('{modal_id}')
YaAuthSuggest.init(
{{
client_id: '{client_id}',
response_type: 'token',
redirect_uri: '{origin}/yandexToken'
}},
'{origin}', {{
parentId: 'yandexAuth',
view: 'button',
buttonSize: 'xxl',
buttonView: 'main',
buttonTheme: 'light',
buttonBorderRadius: '28',
buttonIcon: 'ya',
}}
)
.then(({{
handler
}}) => handler())
.then(data => modalElement.dispatchEvent(
new CustomEvent('yandex.auth.data', {{detail: JSON.stringify(data)}})
))
.catch(error => modalElement.dispatchEvent(
new CustomEvent('yandex.auth.error', {{detail: JSON.stringify(error)}})
))
}}
if (typeof YaAuthSuggest === 'undefined') {{
document.getElementById('yandexAuthScript').onload = yaAuthSuggestAction
}} else {{
yaAuthSuggestAction()
}}
", modal_id = id, origin = window().origin(), client_id = crate::YANDEX_CLIENT_ID).as_str());
Html::VRef(script.into())
}
#[cfg(not(feature = "client"))]
unreachable!()
}} deps={ () } />
<div id="yandexAuth" class="mb-4"></div>
</>
};
#[cfg(not(feature = "yandex"))]
let yandex_html = html! {};

#[cfg(feature = "telegram")]
let telegram_html = html! {
<div class="telegramAuth mb-4">
<div class="telegramAuthContainer">
<script
async=true
src="https://telegram.org/js/telegram-widget.js?22"
data-telegram-login={ crate::TELEGRAM_BOT_LOGIN }
data-size="large"
data-radius="5"
data-onauth={ format!(
"document.getElementById('{modal_id}').dispatchEvent(new CustomEvent('telegram.auth.data', {{detail: JSON.stringify(user)}}))",
modal_id = id
) }
data-request-access="write"
></script>
</div>
</div>
};
#[cfg(not(feature = "telegram"))]
let telegram_html = html! {};

#[cfg(any(feature = "yandex", feature = "telegram"))]
let split_html = html! {
<div style="text-align: center; border-top: var(--bs-border-width) solid var(--bs-border-color);">
<div style="display: inline-block; position: relative; top: -12px; background-color: white; padding: 0px 10px; color: var(--bs-body-color);"> { "ИЛИ" } </div>
</div>
};
#[cfg(not(any(feature = "yandex", feature = "telegram")))]
let split_html = html! {};

html! {
<div
class="modal fade"
Expand Down Expand Up @@ -230,56 +355,9 @@ pub fn login_modal(props: &LoginModalProps) -> Html {
{ message }
</div>
}
<script id="yandexAuthScript" src="https://yastatic.net/s3/passport-sdk/autofill/v1/sdk-suggest-with-polyfills-latest.js"></script>
<DelayedComponent<()> component={ move |_| {
#[cfg(feature = "client")]
{
let script: Element = document().create_element("script").unwrap();
script.set_attribute("type", "text/javascript").unwrap();
script.set_inner_html(format!("
function yaAuthSuggestAction() {{
var modalElement = document.getElementById('{modal_id}')
YaAuthSuggest.init(
{{
client_id: '{client_id}',
response_type: 'token',
redirect_uri: '{origin}/yandexToken'
}},
'{origin}', {{
parentId: 'yandexAuth',
view: 'button',
buttonSize: 'xxl',
buttonView: 'main',
buttonTheme: 'light',
buttonBorderRadius: '28',
buttonIcon: 'ya',
}}
)
.then(({{
handler
}}) => handler())
.then(data => modalElement.dispatchEvent(
new CustomEvent('yandex.auth.data', {{detail: JSON.stringify(data)}})
))
.catch(error => modalElement.dispatchEvent(
new CustomEvent('yandex.auth.error', {{detail: JSON.stringify(error)}})
))
}}
if (typeof YaAuthSuggest === 'undefined') {{
document.getElementById('yandexAuthScript').onload = yaAuthSuggestAction
}} else {{
yaAuthSuggestAction()
}}
", modal_id = id, origin = window().origin(), client_id = crate::YANDEX_CLIENT_ID).as_str());
Html::VRef(script.into())
}
#[cfg(not(feature = "client"))]
unreachable!()
}} deps={ () } />
<div id="yandexAuth" class="mb-4"></div>
<div style="text-align: center; border-top: var(--bs-border-width) solid var(--bs-border-color);">
<div style="display: inline-block; position: relative; top: -12px; background-color: white; padding: 0px 10px; color: var(--bs-body-color);"> { "ИЛИ" } </div>
</div>
{ yandex_html }
{ telegram_html }
{ split_html }
<div class="form-floating mb-3">
<input
type="email"
Expand Down
16 changes: 15 additions & 1 deletion src/content.rs
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,7 @@ impl RequestableItem<LoginQuestion> for API<LoginAnswer> {
}
}

#[cfg(feature = "client")]
#[cfg(all(feature = "client", feature = "yandex"))]
#[async_trait(?Send)]
impl RequestableItem<LoginYandexQuestion> for API<LoginAnswer> {
async fn request(params: LoginYandexQuestion) -> Result<Request, Error> {
Expand All @@ -708,3 +708,17 @@ impl RequestableItem<LoginYandexQuestion> for API<LoginAnswer> {
response.json().await
}
}

#[cfg(all(feature = "client", feature = "telegram"))]
#[async_trait(?Send)]
impl RequestableItem<LoginTelegramQuestion> for API<LoginAnswer> {
async fn request(params: LoginTelegramQuestion) -> Result<Request, Error> {
let url = format!("{url}/api/tlogin", url = crate::API_URL);
Ok(Request::post(url.as_str())
.header("Content-Type", "application/json")
.body(serde_json::to_string(&params).map_err(|e| Error::SerdeError(e))?)?)
}
async fn response(response: Response) -> Result<Self, Error> {
response.json().await
}
}
4 changes: 3 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ pub use app::*;
pub use route::*;
pub use utils::AppContent;

#[cfg(feature = "client")]
#[cfg(all(feature = "client", feature = "yandex"))]
const YANDEX_CLIENT_ID: &'static str = std::env!("YANDEX_CLIENT_ID"); // ee156ec6ee994a748e724f604db8e305
#[cfg(feature = "client")]
const API_URL: &'static str = std::env!("API_URL"); // http://127.0.0.1:3000
#[cfg(feature = "telegram")]
const TELEGRAM_BOT_LOGIN: &'static str = std::env!("TELEGRAM_BOT_LOGIN"); // AnyBlogBot
const TITLE: &'static str = std::env!("TITLE"); // BLOG
const DESCRIPTION: &'static str = std::env!("DESCRIPTION"); // BLOG DESCRIPTION
const KEYWORDS: &'static str = std::env!("KEYWORDS"); // BLOG, KEYWORDS
Expand Down
3 changes: 3 additions & 0 deletions src/utils/logged_user_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ enum LoggedUserInnerState {
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum InProgressStateType {
Default(LoginQuestion),
#[cfg(feature = "yandex")]
Yandex(LoginYandexQuestion),
#[cfg(feature = "telegram")]
Telegram(LoginTelegramQuestion),
}

#[derive(Debug, PartialEq, Eq, Clone)]
Expand Down

0 comments on commit 097cb4b

Please sign in to comment.