2222
2323import jwt
2424from jwt import (
25- PyJWKClient , InvalidTokenError , DecodeError , InvalidSignatureError ,
25+ PyJWKClient , InvalidSignatureError ,
2626 PyJWKClientError , InvalidAudienceError , InvalidIssuerError , ExpiredSignatureError
2727)
2828
2929from firebase_admin import App , _utils , exceptions
3030
31- _FPNV_ATTRIBUTE = '_fpnv '
31+ _FPNV_ATTRIBUTE = '_phone_number_verification '
3232_FPNV_JWKS_URL = 'https://fpnv.googleapis.com/v1beta/jwks'
3333_FPNV_ISSUER = 'https://fpnv.googleapis.com/projects/'
3434_ALGORITHM_ES256 = 'ES256'
3737def _get_fpnv_service (app ):
3838 return _utils .get_app_service (app , _FPNV_ATTRIBUTE , _FpnvService )
3939
40- def verify_token (token : str , app : Optional [App ] = None ) -> FpnvToken :
40+ def verify_token (token : str , app : Optional [App ] = None ) -> PhoneNumberVerificationToken :
4141 """Verifies a Firebase Phone Number Verification (FPNV) token.
4242
4343 Args:
4444 token: A string containing the FPNV JWT.
4545 app: An App instance (optional).
4646
4747 Returns:
48- FpnvToken : The verified token claims.
48+ PhoneNumberVerificationToken : The verified token claims.
4949
5050 Raises:
5151 ValueError: If the token is not a string or is empty.
52- InvalidFpnvTokenError : If the token is invalid or malformed.
53- ExpiredFpnvTokenError : If the token has expired.
52+ InvalidTokenError : If the token is invalid or malformed.
53+ ExpiredTokenError : If the token has expired.
5454 """
5555 return _get_fpnv_service (app ).verify_token (token )
5656
5757
58- class FpnvToken (dict ):
58+ class PhoneNumberVerificationToken (dict ):
5959 """Represents a verified FPNV token.
6060
6161 This class behaves like a dictionary, allowing access to the decoded claims.
@@ -118,23 +118,23 @@ def __init__(self, app):
118118
119119 self ._verifier = _FpnvTokenVerifier (self ._project_id )
120120
121- def verify_token (self , token ) -> FpnvToken :
122- """Verifies the given FPNV token.
121+ def verify_token (self , token ) -> PhoneNumberVerificationToken :
122+ """Verifies a Firebase Phone Number Verification token.
123123
124124 Verifies the signature, expiration, and claims of the token.
125125
126126 Args:
127- token: A string containing the FPNV JWT.
127+ token: A string containing the Firebase Phone Number Verification JWT.
128128
129129 Returns:
130- FpnvToken : The verified token claims.
130+ PhoneNumberVerificationToken : The verified token claims.
131131
132132 Raises:
133133 ValueError: If the token is not a string or is empty.
134- InvalidFpnvTokenError : If the token is invalid or malformed.
135- ExpiredFpnvTokenError : If the token has expired.
134+ InvalidTokenError : If the token is invalid or malformed.
135+ ExpiredTokenError : If the token has expired.
136136 """
137- return FpnvToken (self ._verifier .verify (token ))
137+ return PhoneNumberVerificationToken (self ._verifier .verify (token ))
138138
139139
140140class _FpnvTokenVerifier :
@@ -153,9 +153,9 @@ def verify(self, token) -> Dict[str, Any]:
153153 self ._validate_headers (jwt .get_unverified_header (token ))
154154 signing_key = self ._jwks_client .get_signing_key_from_jwt (token )
155155 claims = self ._decode_and_verify (token , signing_key .key )
156- except (InvalidTokenError , DecodeError , PyJWKClientError ) as exception :
157- raise InvalidFpnvTokenError (
158- 'Verifying FPNV token failed.' ,
156+ except (jwt . InvalidTokenError , PyJWKClientError ) as exception :
157+ raise InvalidTokenError (
158+ 'Verifying phone number verification token failed.' ,
159159 cause = exception ,
160160 http_response = getattr (exception , 'http_response' , None )
161161 ) from exception
@@ -165,18 +165,18 @@ def verify(self, token) -> Dict[str, Any]:
165165 def _validate_headers (self , headers : Any ) -> None :
166166 """Validates the headers."""
167167 if headers .get ('kid' ) is None :
168- raise InvalidFpnvTokenError ( "FPNV has no 'kid' claim." )
168+ raise InvalidTokenError ( "Token has no 'kid' claim." )
169169
170170 if headers .get ('typ' ) != 'JWT' :
171- raise InvalidFpnvTokenError (
172- 'The provided FPNV token has an incorrect type header. ' \
171+ raise InvalidTokenError (
172+ 'The provided token has an incorrect type header. ' \
173173 f"Expected 'JWT' but got { headers .get ('typ' )!r} ."
174174 )
175175
176176 algorithm = headers .get ('alg' )
177177 if algorithm != _ALGORITHM_ES256 :
178- raise InvalidFpnvTokenError (
179- 'The provided FPNV token has an incorrect alg header. '
178+ raise InvalidTokenError (
179+ 'The provided token has an incorrect alg header. '
180180 f'Expected { _ALGORITHM_ES256 } but got { algorithm } .'
181181 )
182182
@@ -192,32 +192,32 @@ def _decode_and_verify(self, token, signing_key) -> Dict[str, Any]:
192192 issuer = expected_issuer
193193 )
194194 except InvalidSignatureError as exception :
195- raise InvalidFpnvTokenError (
196- 'The provided FPNV token has an invalid signature.'
195+ raise InvalidTokenError (
196+ 'The provided token has an invalid signature.'
197197 ) from exception
198198 except InvalidAudienceError as exception :
199- raise InvalidFpnvTokenError (
200- 'The provided FPNV token has an incorrect "aud" (audience) claim. '
199+ raise InvalidTokenError (
200+ 'The provided token has an incorrect "aud" (audience) claim. '
201201 f'Expected { expected_issuer } .'
202202 ) from exception
203203 except InvalidIssuerError as exception :
204- raise InvalidFpnvTokenError (
205- 'The provided FPNV token has an incorrect "iss" (issuer) claim. '
204+ raise InvalidTokenError (
205+ 'The provided token has an incorrect "iss" (issuer) claim. '
206206 f'Expected { expected_issuer } .'
207207 ) from exception
208208 except ExpiredSignatureError as exception :
209- raise ExpiredFpnvTokenError (
210- 'The provided FPNV token has expired.'
209+ raise ExpiredTokenError (
210+ 'The provided token has expired.'
211211 ) from exception
212- except InvalidTokenError as exception :
213- raise InvalidFpnvTokenError (
214- f'Decoding FPNV token failed. Error: { exception } '
212+ except jwt . InvalidTokenError as exception :
213+ raise InvalidTokenError (
214+ f'Decoding token failed. Error: { exception } '
215215 ) from exception
216216
217217 sub_claim = payload .get ('sub' )
218218 if not isinstance (sub_claim , str ) or not sub_claim :
219- raise InvalidFpnvTokenError (
220- 'The provided FPNV token has an incorrect "sub" (subject) claim. '
219+ raise InvalidTokenError (
220+ 'The provided token has an incorrect "sub" (subject) claim. '
221221 'Expected a non-empty string.'
222222 )
223223
@@ -237,14 +237,14 @@ def check_string(cls, label: str, value: Any):
237237 raise ValueError (f'{ label } must be a non-empty string.' )
238238
239239# Firebase Phone Number Verification (FPNV) Errors
240- class InvalidFpnvTokenError (exceptions .InvalidArgumentError ):
241- """Raised when an FPNV token is invalid."""
240+ class InvalidTokenError (exceptions .InvalidArgumentError ):
241+ """Raised when a Firebase Phone Number Verification token is invalid."""
242242
243243 def __init__ (self , message , cause = None , http_response = None ):
244244 exceptions .InvalidArgumentError .__init__ (self , message , cause , http_response )
245245
246- class ExpiredFpnvTokenError ( InvalidFpnvTokenError ):
247- """Raised when an FPNV token is expired."""
246+ class ExpiredTokenError ( InvalidTokenError ):
247+ """Raised when a Firebase Phone Number Verification token is expired."""
248248
249249 def __init__ (self , message , cause = None , http_response = None ):
250- InvalidFpnvTokenError .__init__ (self , message , cause , http_response )
250+ InvalidTokenError .__init__ (self , message , cause , http_response )
0 commit comments