myc_http_tools/functions/
encode_jwt.rs1use crate::{
2 dtos::claims::Claims, models::internal_auth_config::InternalOauthConfig,
3 settings::MYCELIUM_PROVIDER_KEY, utils::HttpJsonResponse,
4};
5
6use actix_web::HttpResponse;
7use chrono::{Duration, Utc};
8use jsonwebtoken::{encode, Algorithm, EncodingKey, Header};
9use myc_core::{domain::dtos::user::User, models::AccountLifeCycle};
10use tracing::error;
11
12pub async fn encode_jwt(
14 user: User,
15 auth_config: InternalOauthConfig,
16 core_config: AccountLifeCycle,
17 is_temporary: bool,
18) -> Result<(String, Duration), HttpResponse> {
19 let expires_in = match match is_temporary {
20 true => auth_config.tmp_expires_in,
21 false => auth_config.jwt_expires_in,
22 }
23 .async_get_or_error()
24 .await
25 {
26 Ok(exp) => exp,
27 Err(err) => {
28 error!("Could not get token expiration: {err}");
29
30 return Err(HttpResponse::InternalServerError().json(
31 HttpJsonResponse::new_message(
32 "Could not get token expiration.".to_string(),
33 ),
34 ));
35 }
36 };
37
38 let duration = chrono::Duration::seconds(expires_in);
39
40 let expiration = match Utc::now().checked_add_signed(duration) {
41 Some(exp) => exp.timestamp(),
42 None => {
43 return Err(HttpResponse::InternalServerError().json(
44 HttpJsonResponse::new_message(
45 "Could not calculate token expiration.".to_string(),
46 ),
47 ));
48 }
49 };
50
51 let claims = Claims {
52 iat: Utc::now().timestamp(),
53 sub: match user.id.to_owned() {
54 Some(id) => id.to_string(),
55 None => "".to_string(),
56 },
57 email: user.email.email(),
58 exp: expiration,
59 iss: MYCELIUM_PROVIDER_KEY.to_string(),
60 aud: core_config
61 .domain_url
62 .ok_or(core_config.domain_name)
63 .map_err(|err| {
64 error!("Could not get domain URL: {err:?}");
65
66 HttpResponse::InternalServerError().json(
67 HttpJsonResponse::new_message(
68 "Unexpected error on build JWT claims".to_string(),
69 ),
70 )
71 })?
72 .async_get_or_error()
73 .await
74 .map_err(|err| {
75 error!("Could not get domain URL: {err:?}");
76
77 HttpResponse::InternalServerError().json(
78 HttpJsonResponse::new_message(
79 "Unexpected error on build JWT claims".to_string(),
80 ),
81 )
82 })?,
83 };
84
85 let header = Header::new(Algorithm::HS512);
86
87 let secret = match auth_config.jwt_secret.async_get_or_error().await {
88 Ok(key) => key,
89 Err(_) => {
90 return Err(HttpResponse::InternalServerError().json(
91 HttpJsonResponse::new_message(
92 "Could not get token secret key.".to_string(),
93 ),
94 ));
95 }
96 };
97
98 match encode(
99 &header,
100 &claims,
101 &EncodingKey::from_secret(secret.as_bytes()),
102 ) {
103 Ok(token) => Ok((token, duration)),
104 Err(err) => Err(HttpResponse::InternalServerError()
105 .json(HttpJsonResponse::new_message(err.to_string()))),
106 }
107}