From 67302965d82a94a90e8f3f01ecd688ace2859792 Mon Sep 17 00:00:00 2001 From: Romain Mallard Date: Sun, 12 Oct 2025 07:55:58 +0200 Subject: [PATCH] add using refresh token to get access token --- db/auth.sqlite | Bin 36864 -> 45056 bytes db/auth.sqlite-shm | Bin 32768 -> 32768 bytes db/auth.sqlite-wal | Bin 20632 -> 193672 bytes refrech_token.sql | 6 ++ src/chat/handlers.rs | 8 +-- src/inventory/handler.rs | 4 +- src/rooms/handler.rs | 4 +- src/utils/auth.rs | 117 +++++++++++++++++++++++++++++++-------- src/utils/routes.rs | 2 +- src/utils/websocket.rs | 2 +- 10 files changed, 111 insertions(+), 32 deletions(-) create mode 100644 refrech_token.sql diff --git a/db/auth.sqlite b/db/auth.sqlite index 61c0241f4b3781751d97a11754368b13b9125d66..5999a376cc34718708f9f4f35be8ec342b92118c 100644 GIT binary patch delta 676 zcmZozz|`=7X@ayM4+8@OHxP3IF(VKQP1G?~$NdEC$l* z>Ws~*C`wB5vs3e6>cJc?=O9aS9jMSg@7PW zU&o-y>-dE0b$~LZ#i>Q{FzF_JcCd{tvN&yQ;(;h>4#%k^9_%O%6h|eXI4VIwBOxulnR#eu>GyczMO*jZj>}ZOMTwEf8;rBF(i~obPQQ z7Zd+u2L7-7kNHn;7F5{FZ!gNstj~y|Fuo+WfLTz0iCLWkMVyn7S)38%%3>y7P(tDV z&cOeDvtYqnepz+~b_Nb!AOMQP04PC$FxO_mgvb2CEX)jyOw7!joLoRLM*cqx{C|LY U-}4Isxy;NQ9B9JqU}0Vk0M(YiKmY&$ delta 432 zcmZp8z|^pSX@ayMI|Bm)ClJE`(?lI(S#}1!E)ib-9}FBkCm8s$`Ooq%;xFg-;gjS! z!Fy-3pnwlgeUl(NySSz%V{>dtVp2|OQEFOIYH>zye zRRL8_L4!*{Au~lG*fq%0(MKU5$kW#`C{n@OHBtvCQCgf@6c3d3^b2uycMVeT^AAz* z3-$5Q;i^|q09zHGkyxCe5aJpElz>YrD5Rv8WhSSBv|>ns%}h*B%`3r_ORXr#1bQPr z5h&;B>lz&5=o^4yZc%C((1R%oPBQ-fKCX^_3NEg0j-fsw3T}=*!LD4I)*Ni&{+g3( z`6VXr=j9bBjyFW{?q+emw}EVo{9hUPzit+s@S0zclaX1R5#*#|CSFh!2!Mqr2Jo|S Gp>P3-s(WAn diff --git a/db/auth.sqlite-shm b/db/auth.sqlite-shm index 5eba869af070c833e25af0fdfbae3276311bd478..51155c7eddc0de5ac13311b844d80f3416d64684 100644 GIT binary patch literal 32768 zcmeI*xlIE>6b9gDE*mglb1vpEV1r0#fC2~z5FLG z*dw8Dq$lm{@&3_Qz}xEUD(cmW=v}1ETB`5o_fh}jc2M1aK0aKwU&hyOcio%Ur|OUI z*S&M!pT=t5&(|qC+NnCJmQ$^yT20kWmCrNjdHrqvZqmE?dCsVNH?MP_=00sL0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5;&sR^{wtcUG5oLYa42@oJafB*pk1PBlyK!5-N0t99+FqdYF z_G2eTvyYZYps>JvnyR}QyM<37o)7FBLAAKv98qY{Vdr<225ToP9sU?tE1 delta 195 zcmZo@U}|V!s+V}A%K!o_K+MR%AixTwIf3}zBD(^UAVJnDjf$BK8`X@tPROy|`W3-Q zs(PSNU;r}rKN5fnOF?O{AsLbh`{qa06uu21kXKqe!Y*G7YvNTZf^bHd6GDwU>{i=F+i4q{s^rCL z2tWV=5P$##AOHaf{2Bxn#0HD#a&e1Ci}J{%Qcy+_vZ~JI3*?@ya`U7!>eQrsV#PvqHxa$@oz6P5*e_PAxa?FDKDIDBO|_GHS<*Tu zUpuLXB{eyXwUfG8Qu;h!U;1Nep-Zh@;HN+Tm?`^>502A^f1_~KAY2!&3KvQ#v48*s zAOHafKmY;|fB*y_009UGqL^%vM}KGSgi)qAd$Qq%VgXcK`p7C~t>77%~{1Rwwb2tWV=5P$##AOHafY;*yh zx6|i+8$A!Lzkqkwr@!w1uj^Ub7{HOv0_ZP5bud8y0uX=z1Rwwb2tWV=5P$##HlIML zzW^Odz^=6m{Nkys=lfyv<7gMyeAgRi1OW&@00Izz00bZa0SG_<0uU${DD@ZM=sK-k z;0I%0e$TyU{&>fsp%4jEDvjm~S-B{ANoWG2(XdC7NK)30K$i6V0~49ImzHF~CRU#I zrOMK7=sML*qng&+E*l#sgbTtMVNM7&?yxu6F53p#59`NJB|la}00Izz00bZa0SG`~ zjRFfI2~_WLaf?SQ1J%>8UKMe^^a1OWW!o2;?6-=Ftg@(jeWdoXqLdun_gbU2Co&`^ zdoUcM;nbyYBqoL9p-_jEEaoT34#s75ycDv%Y+G8H&7>5TlSOkc+eAZ|CFC(BSFFsY z3*Wx9FQ>oJEXG~cVz^hFaKc@&s)0N$e00FEx*|Nf?Bqd%3zDpTn?L+n4@Qw&=FCNNvgTD=`=i4)~+P(!s#6SY_-a&lJbAUU1$ z$2f~9irnH(Rwj#+cPm()EECPJHz*{`BE9^x@wqTr~*Sg{#5^ngSC9AOHafKmY;|fB*y_009U<00Qe+U>o0T z;$8K+7Ao4<*ks}z`n6V$7dh5GK*tqi?E_l7zzc1WfA?I=-JtCPr8tG__>^&I5P$## zAOHafKmY;|fB*y_009Wxg+O_nLMzR$wF~Sy-*NFjzBBazZ5JRf4;X|S?0o_H&HxKt zNLOQm00bZa0SG_<0uX=z1Rwwb2tZ&%3zWADu;+cPUEo^#Km1eRhyG7t+`$cfeR1#* zfB*y_009U<00Izz00bZaftmuPcm%XBz*2t!d*3{`1(*QNKKJNSpczYpyKZ%T%h5P$## zAOHafKmY;|fB*y_0D(;-Q0gzBi&J?12dN!@)4DxP8w(JpaMN6BoCpLU009U<00Izz z00bZa0SIha8DUNcHSVxmZ5M5)Z4vUr z#zU-jN%ugsey3eH4mdvD+QZO6~><>hx!Dw*6A03ts28JbnJQfLt z$uSHB!Z9fx4i3cwQaBQm!tqe3LrTu5N+D66xoq359gNHBcv6Z5j*vXJ^QD#9OiE!n z*`_Kb%VSEeSebh~UsNWw-7XdD^lvqbaTjOE@@RqPszsZEVZQS*3&Ibj}~+ETSlKi#u7FwBD-h!>G&8Dzv)RJA&@D zRBJ0M_LQuubNK?f;i}a9bVi+;luxW!i0%%ccdgS|XBPX#Y898AYQo1BW~ZrkQZGwd z=j3ZA^{}KSr?GZYH%m&N=j%&t0$kE`!kF$u*Uz)AUgyg009U<00Izz z00bZa0SG|gtrZ~S3)Jy0{YV0|(XpwHcj(uyFuuTvAN}4@``Pbqr|klylK{pScx$gA z_67k6KmY;|fB*y_009U<00NssU?Yt$V5Q{Rdj#rO?vYP?|B`}n2RBDW#92T90uX=z z1Rwwb2tWV=5P-njBCwI#1?UiiOYH*pe&~N+QXc==O}3Ku7r?lKZ%YNjP9XpR2tWV= z5P$##AOHafKmY>2NrAF)2kH2MOYH(L$NurtpK<)rwbH(gWJ#L{=vV}-UqNX-77%~{ z1Rwwb2tWV=5P$##AOHafY;Xadx6|i+HtxUn9>Jjav@$dE2WJtdaD!i596kgf009U< z00Izz00bZa0SG`~1%a~u0(2+=yVfpn@slrk4}32Ay<6=9m*{&0msThSn;-xI2tWV= z5P$##AOHafKmY;|SZ4wbK5iZL^~x!C_ef{Y?o_JN=k4`$%00V!JG+%`&xj}GP5XNL zO8o^ma`;Q_0zba*r3*iP_J@myhC(F9s5F`{WaXmdC7}t7M#COSB550GdNR}Z4`{r@ zcaqseW^JP7)tVX&U8kDucB{dupl;AM3;+OJX#s3o`&_(1*E4d^a1OWWcz|hV%@K*hy^!E>2Po- z@2%XKZb$l^wCJ|ANNvds3AP>#$7q~%X)qcb@JENGgMnemACEthzO80)z)>v>yiO+J(S5b|HLX6YTbI=)yumfnE43KM zl?pjk>!8^zwzqS`OhcWXBu|M6Rhgbqaw%omR|~0r{#ZbY`S*qb(z1 zW1K}4MQ(8?E0fkAm3`IBs2a*cJK?zL1eD{qP^Sykuq1yT*G)a`Ueotl(StXPPy zj???n>8vx0{bIF>%T6odV+*s>R6D7cC9QMvwUc^SQj^nIJE@x`rO)&99RfP(;t`zu z(ET6&okw1H#V*`1aKd4OaF~2xf&c^{009U<00Izz00bZa0SG|gP6XC_JOXkq)_Oac z$S=C_1)lj_^NDXoJfQ~RCTSOV!yvptJ}^N50uX=z1Rwwb2tWV=5P$##Ah4+f==cKU zglPYN-S`4yU-^9anJv#geyd%8j4yBr;|px63y+h500bZa0SG_<0uX=z1Rwx`O)s$8 z@dXG3Z5PnJN3iSsOCLMj?5U@X1!PbGyhlJCFhKwU5P$##AOHafKmY;|fB*#UOkl&l zNAPdspZ}5fmBx?Lcm%9n0Phjp*_B6X2tWV=5P$##AOHafKmY;|fWQV2sP-O#@`r^-s0Y_Xv!_6@zeHxFTG*T{eD$00bZa0SG_<0uX=z1Rwwb2tZ(63T)$>>v)${ z7k-n(S>0O4J2>4+qm|=Dj>Ri9k~7hbFYwHQvFq=QJx6J~04F32LIQCL*X7m5K|ufl z5P$##AOHafKmY;|fWUed(8d>-|81kyz|BYE?bdo@t6Uh%=RBEo>ukTfuQf|Pd_B85 ziv6CBseX5BDB%C#NN~b8klo++VEhB^Y9V)cXsC79zDRa9;@}mI7z#JQV<^a?EZHv-~H$N zKk{YTSU}?uV1fVyAOHafKmY;|fB*y_009UjSWY#9SuGVBTbe(FplTZg%+mpt|3E_fpMwk;qjXP{l z+W*D=CEH)tDgfId009U<00Izz00bZafj1YJ&sZ&@%f&5nMR{aW(PEa*KW4Mcf5gT% z&8uYTaBz$F>yi}n6G~1?&%QM5iw69$fE4rZ4F#kY-L@8~twEA9X(BKOTz&!zA}WAROx;>1dqvgqC>0Wnue2`L3$_U$EUuvUs>^k_0=%dfg!= zb%&Ug+LD=cvi1>5@o;b`9+1M3m=unOLLE}FbilVWmu+J^PK?Xycv6Z5j*vXJ^QD#9 zOiCfATG~{lWO+=<6)SU(=ZnhZ?aW%a&OWPI9B^=kOfIb)SEnb*(^^8FDdyStgzlsh z9^Kb1ef6u)>egj#P_2Vzv)JCw4YP|-+OMii&nUT+vh1rxcOjN-Y|F`6rGw;j&L86} zq9}5UJ6V~OS!EwaU4G`TuJr=ay;i*rQ?jbgR63(hP0A-$EadhDE8PZ8XPsH> z7pq+=cB%;9~VN;i^HnE?gD73HlPG4V z_^nMw-chexZ{>KAW9r})Zox{?!a8puCP5P$##AOHafKmY;|fB*y_ z009VWLIIwyr|%Nz#vOd_#PjbzHqiPfXcyRo7aXSq0SG_<0uX=z1Rwwb2tWV=5GWJi Id3*i;10m6X>;M1& literal 20632 zcmeI)&u`mg7zc1WZIiTX7A8Oj!Qs`2Xib|gKbKV~h;(&FR5xBzM_Z7Ite5sZd~BFe*l4yxNzgl1&IUG#DUvRaM)o7#P-@Ia_EA-WwZ&(R3bDzEt3g2gflXscZ z*TO%BZ-uXi#nUfO-VNOuHW>X7fB*y_009U<00Izz00jO{VE0TQ!0|kL^F3Q#Z|GgU z*43>I#co~GP0OkE+m8ZX84&O|Jb1Av{7SA^ zCd)#3mUi?ky{pjPd_fj22}M$nWKt-JqSNQ@in5_v8$=ea()L4rn!aUJb!X(UE_X_` zuABDpzOKGSk53~Dk|YYb0$CK6awSnFOF3~(nBdwJ##h|73Yo4LTIE3U5H!h^WGP>ugI0usOiG3PYDsv^N!$sXPp#~U9S>-$mUX?= zrPI6I#{)FOYB$sy|2WA;%hnt8lpX9N&yV@JEH}v8JuD^VzWDjk;h{-4bc`Pv9-44N zM|t1y(6}4wT+2Jx_fGNT1>X4X`v8nLynvGvc=EhJ=#(cf5ITjtfO}T3fdB*` z009U<00Izz00d4f@Gs;A`h~sB!S0o3BXfYfz@W>15|x?W&qYS8^_&t4x{E--Fky}, - AuthClaims {user_id, hotel_id, username}: AuthClaims, + AuthClaims {user_id, hotel_id}: AuthClaims, CreateConversationPayload(payload): CreateConversationPayload ) -> impl IntoResponse { @@ -48,7 +48,7 @@ pub async fn create_conversation( pub async fn add_user_to_conv( State(state): State, - AuthClaims {user_id, hotel_id,username}: AuthClaims, + AuthClaims {user_id, hotel_id}: AuthClaims, AddUserConversationPayload(payload):AddUserConversationPayload ) -> impl IntoResponse { @@ -102,7 +102,7 @@ pub async fn add_user_to_conv( pub async fn send_message( State(state): State, - AuthClaims {user_id, hotel_id,username}: AuthClaims, + AuthClaims {user_id, hotel_id}: AuthClaims, SendMessagePayload(payload):SendMessagePayload ) -> impl IntoResponse { @@ -187,7 +187,7 @@ struct Message { pub async fn get_message( State(state): State, - AuthClaims {user_id, hotel_id,username}: AuthClaims, + AuthClaims {user_id, hotel_id}: AuthClaims, GetMessagesPayload(payload):GetMessagesPayload ) -> Result { diff --git a/src/inventory/handler.rs b/src/inventory/handler.rs index 0baf5f0..72e104e 100644 --- a/src/inventory/handler.rs +++ b/src/inventory/handler.rs @@ -13,7 +13,7 @@ use crate::utils::{auth::AuthClaims, db_pool::AppState}; pub async fn create_inventory_item( State(state): State, Path((item_name, item_amount)): Path<(String, i32)>, - AuthClaims{ user_id, hotel_id, username}: AuthClaims, + AuthClaims{ user_id, hotel_id}: AuthClaims, ) -> impl IntoResponse { let pool = state.hotel_pools.get_pool(hotel_id); @@ -37,7 +37,7 @@ pub async fn create_inventory_item( pub async fn update_inventory_item( State(state): State, Path((item_id, item_amount)): Path<(i32, i32)>, - AuthClaims { user_id, hotel_id, username }: AuthClaims, + AuthClaims { user_id, hotel_id }: AuthClaims, ) -> impl IntoResponse { //TODO: make better error handling : diff --git a/src/rooms/handler.rs b/src/rooms/handler.rs index ea01c5b..8212f4f 100644 --- a/src/rooms/handler.rs +++ b/src/rooms/handler.rs @@ -26,7 +26,7 @@ pub async fn hello_rooms() -> String { pub async fn fake_db_update( State(state): State, - AuthClaims { user_id, hotel_id, username }: AuthClaims, + AuthClaims { user_id, hotel_id }: AuthClaims, Path(room_id): Path, UpdateRoomPayload(payload): UpdateRoomPayload, ) -> impl IntoResponse { @@ -52,7 +52,7 @@ pub async fn fake_db_update( pub async fn clean_db_update( State(state): State, Path(room_id): Path, - AuthClaims { user_id, hotel_id, username }: AuthClaims, + AuthClaims { user_id, hotel_id }: AuthClaims, UpdateRoomPayload(payload): UpdateRoomPayload, ) -> impl IntoResponse { diff --git a/src/utils/auth.rs b/src/utils/auth.rs index 2689d2a..d8dd782 100644 --- a/src/utils/auth.rs +++ b/src/utils/auth.rs @@ -1,12 +1,6 @@ use std::time::Duration; use axum::{ - body::{to_bytes, Body}, - http::{Request as HttpRequest, StatusCode, header::{SET_COOKIE, HeaderValue} }, - http::request::Parts, - middleware::Next, - response::{Response, IntoResponse}, - Json, - extract::{Path, State, FromRequest, FromRequestParts, Extension} + body::{to_bytes, Body}, extract::{Extension, FromRequest, FromRequestParts, Path, State}, http::{header::{HeaderValue, SET_COOKIE}, request::Parts, Request as HttpRequest, StatusCode }, middleware::Next, response::{IntoResponse, IntoResponseParts, Response}, Json }; use axum_extra::extract::TypedHeader; @@ -44,11 +38,11 @@ pub struct JwtKeys { pub async fn token_tester( State(state): State, //Extension(keys): Extension, - AuthClaims { user_id, hotel_id, username }: AuthClaims, + AuthClaims { user_id, hotel_id }: AuthClaims, ) -> impl IntoResponse { format!( - "Hello {} (user_id: {}) from hotel {}", - username, user_id, hotel_id + "(user_id: {}) from hotel {}", + user_id, hotel_id ) } @@ -58,7 +52,7 @@ pub struct AuthUser(pub Claims); //?? pub struct AuthClaims { pub user_id: i32, pub hotel_id: i32, - pub username: String, + //pub username: String, } impl FromRequestParts for AuthClaims @@ -96,7 +90,7 @@ where Ok(AuthClaims { user_id: token_data.claims.id, hotel_id: token_data.claims.hotel_id, - username: token_data.claims.username, + //username: token_data.claims.username, }) } @@ -381,7 +375,7 @@ pub async fn clean_auth_loging( let claims = serde_json::json!({ "id": user_id, - "hotel_id": payload.hotel_id, + "hotel_id": hotel_id, "username": payload.username, "exp": expiration }); @@ -402,7 +396,7 @@ pub struct CreateRefreshTokenValue { pub username: String, pub password: String, pub device_id: Uuid, - pub timestamp: Option, + //pub timestamp: Option, } @@ -424,28 +418,29 @@ pub async fn create_refresh_token( let mut bytes = [0u8; 64]; OsRng.fill_bytes(&mut bytes); + let raw_token = Uuid::new_v4().to_string(); + let hashed_token = argon2 - .hash_password(&bytes, &salt) + .hash_password(raw_token.as_bytes(), &salt) .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))? .to_string(); - let raw_token = general_purpose::STANDARD.encode(&bytes); - let conn = state.logs_pool.get() .map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "DB connection error".to_string()))?; let user_row = conn.query_row( - "SELECT id, password FROM users WHERE username = ?1", + "SELECT id, password, hotel_id FROM users WHERE username = ?1", params![&payload.username], |row| { let user_id: i32 = row.get(0)?; let password: String = row.get(1)?; - Ok((user_id, password)) + let hotel_id: i32 = row.get(2)?; + Ok((user_id, password, hotel_id)) }, ).optional() .map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "DB get user id error".to_string()))?; - let (user_id, stored_hash) = user_row + let (user_id, stored_hash, hotel_id) = user_row .ok_or((StatusCode::NOT_FOUND, "User not found".to_string()))?; if !verify_password(&payload.password, &stored_hash) { @@ -453,8 +448,8 @@ pub async fn create_refresh_token( } conn.execute( - "INSERT INTO refresh_token (user_id, token_hash, device_id, user_agent) VALUES (?1, ?2, ?3, ?4)", - params![user_id, hashed_token, device_id_str, user_agent_str], + "INSERT INTO refresh_token (user_id, token_hash, device_id, user_agent, hotel_id) VALUES (?1, ?2, ?3, ?4, ?5)", + params![user_id, hashed_token, device_id_str, user_agent_str, hotel_id], ) .map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "DB insert error".to_string()))?; @@ -469,6 +464,84 @@ pub async fn create_refresh_token( Ok(response) // ← Wrap in Ok() } +#[derive(Deserialize)] +pub struct LoginRefreshTokenValues{ + device_id: Uuid, + refresh_token: String, +} + +pub async fn login_refresh_token ( + State(state): State, + Extension(keys): Extension, + user_agent: Option>, + Json(payload): Json +) -> impl IntoResponse { + + let conn = match state.logs_pool.get() { + Ok(c) => c, + Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "DB connection error").into_response(), + }; + + let user_agent_str = user_agent + .map(|ua| ua.to_string()) + .unwrap_or_else(|| "Unknown".to_string()); + + let device_id_str = payload.device_id.to_string(); + + //"SELECT user_id, token_hash, hotel_id FROM refresh_token WHERE device_id = ?1 AND user_agent = ?2", + + let device_row = match conn.query_row( + "SELECT user_id, token_hash, hotel_id FROM refresh_token WHERE device_id = ?1 AND user_agent = ?2", + params![&device_id_str, &user_agent_str], + |row| { + let user_id: i32 = row.get(0)?; + let token_hash: String = row.get(1)?; + let hotel_id: i32 = row.get(2)?; + //let displayname: String = row.get(3)?; + Ok((user_id, token_hash, hotel_id)) + }, + ).optional() { + Ok(opt) => opt, + Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "DB query error").into_response(), + }; + + + let (user_id, token_hash, hotel_id) = match device_row { + Some(tuple) => tuple, + None => return (StatusCode::UNAUTHORIZED, "No matching device").into_response(), + }; + + + if !verify_password(&payload.refresh_token, &token_hash) { + return (StatusCode::UNAUTHORIZED, "Invalid or mismatched token").into_response(); +} + + + let expiration = match chrono::Utc::now().checked_add_signed(chrono::Duration::hours(15)) { + Some(time) => time.timestamp() as usize, + None => { + // Handle overflow — probably a 500, since this should never happen + return (StatusCode::INTERNAL_SERVER_ERROR, "Time overflow".to_string()).into_response(); + } +}; + + let claims = serde_json::json!({ + "id": user_id, + "hotel_id": hotel_id, + //"username": payload.username, + "exp": expiration + }); + + let token = match encode( + &Header::default(), + &claims, + &keys.encoding + ) { + Ok(t) => t, + Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "JWT creation failed").into_response(), + }; + Json(LoginResponse { token }).into_response() +} fn internal_error(err: E) -> (StatusCode, String) { (StatusCode::INTERNAL_SERVER_ERROR, format!("Internal error: {}", err)) diff --git a/src/utils/routes.rs b/src/utils/routes.rs index 9e00831..1f744aa 100644 --- a/src/utils/routes.rs +++ b/src/utils/routes.rs @@ -22,6 +22,6 @@ pub fn utils_routes() -> Router { .route("/update_password", put(UpdatePassword)) .route("/create_refresh", post(create_refresh_token)) - + .route("/login_refresh_token", post(login_refresh_token)) //.with_state(state) } \ No newline at end of file diff --git a/src/utils/websocket.rs b/src/utils/websocket.rs index 793cdb5..8c743d6 100644 --- a/src/utils/websocket.rs +++ b/src/utils/websocket.rs @@ -89,7 +89,7 @@ async fn handle_socket( } pub async fn ws_handler( - AuthClaims {user_id, hotel_id,username}: AuthClaims, + AuthClaims {user_id, hotel_id}: AuthClaims, ws: WebSocketUpgrade, State(state): State, //Path((hotel_id, user_id)): Path<(i32, i32)>,