Handle a token refresh request. Validate the new JWT, and if it belongs to the same tenant, upgrade the session with the new credentials. Invalid tokens keep the existing session credentials and respond with an error.
(
&mut self,
msg: &TokenRefreshMsg,
jwt_validator: &JwtValidator,
)
| 17 | /// new credentials. Invalid tokens keep the existing session |
| 18 | /// credentials and respond with an error. |
| 19 | pub fn handle_token_refresh( |
| 20 | &mut self, |
| 21 | msg: &TokenRefreshMsg, |
| 22 | jwt_validator: &JwtValidator, |
| 23 | ) -> Option<SyncFrame> { |
| 24 | self.last_activity = Instant::now(); |
| 25 | |
| 26 | if msg.new_token.is_empty() { |
| 27 | let ack = TokenRefreshAckMsg { |
| 28 | success: false, |
| 29 | error: Some("empty token".into()), |
| 30 | expires_in_secs: 0, |
| 31 | }; |
| 32 | return SyncFrame::try_encode(SyncMessageType::TokenRefreshAck, &ack); |
| 33 | } |
| 34 | |
| 35 | match jwt_validator.validate(&msg.new_token) { |
| 36 | Ok(new_identity) => { |
| 37 | if let Some(current_tenant) = self.tenant_id |
| 38 | && new_identity.tenant_id != current_tenant |
| 39 | { |
| 40 | warn!( |
| 41 | session = %self.session_id, |
| 42 | current_tenant = current_tenant.as_u64(), |
| 43 | new_tenant = new_identity.tenant_id.as_u64(), |
| 44 | "token refresh rejected: tenant mismatch" |
| 45 | ); |
| 46 | let ack = TokenRefreshAckMsg { |
| 47 | success: false, |
| 48 | error: Some("tenant mismatch".into()), |
| 49 | expires_in_secs: 0, |
| 50 | }; |
| 51 | return SyncFrame::try_encode(SyncMessageType::TokenRefreshAck, &ack); |
| 52 | } |
| 53 | self.username = Some(new_identity.username.clone()); |
| 54 | self.identity = Some(new_identity); |
| 55 | info!( |
| 56 | session = %self.session_id, |
| 57 | "JWT token refreshed successfully" |
| 58 | ); |
| 59 | let ack = TokenRefreshAckMsg { |
| 60 | success: true, |
| 61 | error: None, |
| 62 | expires_in_secs: 3600, |
| 63 | }; |
| 64 | SyncFrame::try_encode(SyncMessageType::TokenRefreshAck, &ack) |
| 65 | } |
| 66 | Err(e) => { |
| 67 | warn!( |
| 68 | session = %self.session_id, |
| 69 | error = %e, |
| 70 | "token refresh FAILED — keeping existing credentials" |
| 71 | ); |
| 72 | let ack = TokenRefreshAckMsg { |
| 73 | success: false, |
| 74 | error: Some(e.to_string()), |
| 75 | expires_in_secs: 0, |
| 76 | }; |