1- import { decodeBase64UrlBytes } from "./base64" ;
1+ import { decodeBase64Url } from "./base64" ;
22import { JwtError , JwtErrorCode } from "./errors" ;
3+ import { utf8Decoder , utf8Encoder } from "./utf8" ;
34import { isNonEmptyString , isNumber , isString } from "./validator" ;
45
56export interface TokenDecoder {
@@ -10,7 +11,7 @@ export interface JsonWebKeyWithKid extends JsonWebKey {
1011 kid : string ;
1112}
1213
13- type DecodedHeader = { kid : string ; alg : "RS256" } & Record < string , any > ;
14+ export type DecodedHeader = { kid : string ; alg : "RS256" } & Record < string , any > ;
1415
1516export type DecodedPayload = {
1617 aud : string ;
@@ -52,7 +53,7 @@ export class RS256Token {
5253 return new RS256Token ( token , {
5354 header,
5455 payload,
55- signature : decodeBase64UrlBytes ( tokenParts [ 2 ] ) ,
56+ signature : decodeBase64Url ( tokenParts [ 2 ] ) ,
5657 } ) ;
5758 }
5859
@@ -61,7 +62,7 @@ export class RS256Token {
6162
6263 // `${token.header}.${token.payload}`
6364 const trimmedSignature = rawToken . substring ( 0 , rawToken . lastIndexOf ( "." ) ) ;
64- return new TextEncoder ( ) . encode ( trimmedSignature ) ;
65+ return utf8Encoder . encode ( trimmedSignature ) ;
6566 }
6667}
6768
@@ -93,42 +94,42 @@ const decodePayload = (
9394 if ( ! isNonEmptyString ( payload . aud ) ) {
9495 throw new JwtError (
9596 JwtErrorCode . INVALID_ARGUMENT ,
96- `"aud" claim must be a string but got ${ payload . aud } } `
97+ `"aud" claim must be a string but got " ${ payload . aud } " `
9798 ) ;
9899 }
99100
100101 if ( ! isNonEmptyString ( payload . sub ) ) {
101102 throw new JwtError (
102103 JwtErrorCode . INVALID_ARGUMENT ,
103- `"sub" claim must be a string but got ${ payload . sub } }`
104+ `"sub" claim must be a string but got " ${ payload . sub } }" `
104105 ) ;
105106 }
106107
107108 if ( ! isNonEmptyString ( payload . iss ) ) {
108109 throw new JwtError (
109110 JwtErrorCode . INVALID_ARGUMENT ,
110- `"iss" claim must be a string but got ${ payload . iss } }`
111+ `"iss" claim must be a string but got " ${ payload . iss } }" `
111112 ) ;
112113 }
113114
114115 if ( ! isNumber ( payload . iat ) ) {
115116 throw new JwtError (
116117 JwtErrorCode . INVALID_ARGUMENT ,
117- `"iat" claim must be a number but got ${ payload . iat } }`
118+ `"iat" claim must be a number but got " ${ payload . iat } }" `
118119 ) ;
119120 }
120121
121122 if ( currentTimestamp < payload . iat ) {
122123 throw new JwtError (
123124 JwtErrorCode . INVALID_ARGUMENT ,
124- `Incorrect "iat" claim must be a newer than "${ currentTimestamp } " (iat: ${ payload . iat } )`
125+ `Incorrect "iat" claim must be a newer than "${ currentTimestamp } " (iat: " ${ payload . iat } " )`
125126 ) ;
126127 }
127128
128129 if ( ! isNumber ( payload . exp ) ) {
129130 throw new JwtError (
130131 JwtErrorCode . INVALID_ARGUMENT ,
131- `"exp" claim must be a number but got ${ payload . exp } }`
132+ `"exp" claim must be a number but got " ${ payload . exp } " }`
132133 ) ;
133134 }
134135
@@ -143,21 +144,9 @@ const decodePayload = (
143144} ;
144145
145146const decodeBase64JSON = ( b64Url : string ) : any => {
146- let b64 = b64Url . replace ( / - / g, "+" ) . replace ( / _ / g, "/" ) ;
147- switch ( b64 . length % 4 ) {
148- case 0 :
149- break ;
150- case 2 :
151- b64 += "==" ;
152- break ;
153- case 3 :
154- b64 += "=" ;
155- break ;
156- default :
157- throw new Error ( "Illegal base64url string." ) ;
158- }
147+ const decoded = decodeBase64Url ( b64Url )
159148 try {
160- return JSON . parse ( decodeURIComponent ( atob ( b64 ) ) ) ;
149+ return JSON . parse ( utf8Decoder . decode ( decoded ) ) ;
161150 } catch {
162151 return null ;
163152 }
0 commit comments