1- use crate :: { debug_log, get_config_content} ;
2- use hmac:: { Hmac , Mac } ;
3- use jwt:: { Header , SignWithKey , Token , VerifyWithKey } ;
4- use sha2:: Sha256 ;
1+ use crate :: get_config_content;
2+ use jsonwebtoken:: { decode, encode, DecodingKey , EncodingKey , Header , Validation } ;
3+ use serde:: { Deserialize , Serialize } ;
54use std:: collections:: BTreeMap ;
65use toml:: value:: Table ;
7- pub fn verify_jwt_token ( token_str : & str ) -> Result < BTreeMap < String , String > , jwt:: Error > {
8- // config.toml, jwt_secret parameter
6+
7+ #[ derive( Debug , Serialize , Deserialize ) ]
8+ struct Claims {
9+ email : String ,
10+ }
11+
12+ fn verify_with_key_str (
13+ token_str : & str ,
14+ key_str : & str ,
15+ ) -> Result < BTreeMap < String , String > , jsonwebtoken:: errors:: Error > {
16+ let key = DecodingKey :: from_secret ( key_str. as_bytes ( ) ) ;
17+ let mut validation = Validation :: default ( ) ;
18+ validation. required_spec_claims . clear ( ) ;
19+ validation. validate_exp = false ;
20+ let token_data = decode :: < Claims > ( token_str, & key, & validation) ?;
21+ let mut claims = BTreeMap :: new ( ) ;
22+ claims. insert ( "email" . to_string ( ) , token_data. claims . email ) ;
23+ Ok ( claims)
24+ }
25+
26+ pub fn verify_jwt_token (
27+ token_str : & str ,
28+ ) -> Result < BTreeMap < String , String > , jsonwebtoken:: errors:: Error > {
929 let toml_cfg = get_config_content ( ) ;
1030 let parsed_toml = toml_cfg. parse :: < Table > ( ) . unwrap ( ) ;
11- let key_str = parsed_toml[ "jwt_secret" ] . as_str ( ) . unwrap ( ) ;
12- let key: Hmac < Sha256 > = Hmac :: new_from_slice ( key_str. as_bytes ( ) ) ?;
13- let verify_result = token_str. verify_with_key ( & key) ;
14- let token: Token < Header , BTreeMap < String , String > , _ > = match verify_result {
15- Ok ( token) => token,
16- Err ( e) => {
17- eprintln ! ( "JWT verification error: {:?}" , e) ;
18- return Err ( e) ;
19- }
20- } ;
21- //let header = token.header();
22- let claims = token. claims ( ) ;
23- let email = claims. get ( "email" ) ;
24- match email {
25- Some ( email) => {
26- debug_log ! ( "email: {}" , email) ;
31+
32+ // If only unified_secret is configured, it serves as jwt_secret as well.
33+ // Try jwt_secret first, then fall through to unified_secret.
34+ if let Some ( key_str) = parsed_toml. get ( "jwt_secret" ) . and_then ( |v| v. as_str ( ) ) {
35+ match verify_with_key_str ( token_str, key_str) {
36+ Ok ( claims) => {
37+ debug_log ! ( "email: {}" , claims[ "email" ] ) ;
38+ return Ok ( claims) ;
39+ }
40+ Err ( e) => {
41+ debug_log ! ( "JWT verification with jwt_secret failed: {:?}" , e) ;
42+ }
2743 }
28- None => {
29- debug_log ! ( "email not found" ) ;
30- return Err ( jwt:: Error :: InvalidSignature ) ;
44+ }
45+
46+ if let Some ( unified) = parsed_toml. get ( "unified_secret" ) . and_then ( |v| v. as_str ( ) ) {
47+ match verify_with_key_str ( token_str, unified) {
48+ Ok ( claims) => {
49+ debug_log ! ( "email (unified_secret): {}" , claims[ "email" ] ) ;
50+ return Ok ( claims) ;
51+ }
52+ Err ( e) => {
53+ eprintln ! ( "JWT verification with unified_secret also failed: {:?}" , e) ;
54+ return Err ( e) ;
55+ }
3156 }
3257 }
33- Ok ( claims. clone ( ) )
58+
59+ Err ( jsonwebtoken:: errors:: ErrorKind :: InvalidSignature . into ( ) )
3460}
3561
3662pub fn generate_jwt_secret ( ) {
@@ -45,13 +71,18 @@ pub fn generate_jwt_secret() {
4571 debug_log ! ( "jwt_secret=\" {}\" " , secret) ;
4672}
4773
48- pub fn generate_jwt_token ( email : & str ) -> Result < String , jwt :: Error > {
74+ pub fn generate_jwt_token ( email : & str ) -> Result < String , jsonwebtoken :: errors :: Error > {
4975 let toml_cfg = get_config_content ( ) ;
5076 let parsed_toml = toml_cfg. parse :: < Table > ( ) . unwrap ( ) ;
51- let key_str = parsed_toml[ "jwt_secret" ] . as_str ( ) . unwrap ( ) ;
52- let key: Hmac < Sha256 > = Hmac :: new_from_slice ( key_str. as_bytes ( ) ) ?;
53- let mut claims = BTreeMap :: new ( ) ;
54- claims. insert ( "email" . to_string ( ) , email. to_string ( ) ) ;
55- let token_str = claims. sign_with_key ( & key) ?;
56- Ok ( token_str)
77+ // For token generation, prefer jwt_secret, fall back to unified_secret
78+ let key_str = parsed_toml
79+ . get ( "jwt_secret" )
80+ . or_else ( || parsed_toml. get ( "unified_secret" ) )
81+ . and_then ( |v| v. as_str ( ) )
82+ . expect ( "config must define jwt_secret or unified_secret" ) ;
83+ let key = EncodingKey :: from_secret ( key_str. as_bytes ( ) ) ;
84+ let claims = Claims {
85+ email : email. to_string ( ) ,
86+ } ;
87+ encode ( & Header :: default ( ) , & claims, & key)
5788}
0 commit comments