|
1 | | -import assertString from './util/assertString'; |
2 | | -import isBase64 from './isBase64'; |
| 1 | +import assertString from './util/assertString' |
3 | 2 |
|
4 | | -export default function isJWT(str) { |
5 | | - assertString(str); |
| 3 | +function decodeBase64Url (str) { |
| 4 | + str = str.replace(/-/g, '+').replace(/_/g, '/') |
| 5 | + const pad = str.length % 4 |
| 6 | + if (pad) str += '='.repeat(4 - pad) |
6 | 7 |
|
7 | | - const dotSplit = str.split('.'); |
8 | | - const len = dotSplit.length; |
| 8 | + if (typeof Buffer !== 'undefined') { |
| 9 | + // Node.js |
| 10 | + return Buffer.from(str, 'base64').toString('utf8') |
| 11 | + } else if (typeof atob !== 'undefined') { |
| 12 | + // Browser |
| 13 | + return atob(str) |
| 14 | + } else { |
| 15 | + throw new Error('No base64 decoder available') |
| 16 | + } |
| 17 | +} |
| 18 | + |
| 19 | +export default function isJWT (str) { |
| 20 | + assertString(str) |
| 21 | + |
| 22 | + const parts = str.split('.') |
| 23 | + if (parts.length !== 3) return false |
| 24 | + try { |
| 25 | + const header = JSON.parse(decodeBase64Url(parts[0])) |
| 26 | + const payload = JSON.parse(decodeBase64Url(parts[1])) |
| 27 | + |
| 28 | + if (typeof header !== 'object' || header === null) return false |
| 29 | + if (typeof payload !== 'object' || payload === null) return false |
| 30 | + if (typeof header.alg !== 'string') return false |
9 | 31 |
|
10 | | - if (len !== 3) { |
11 | | - return false; |
| 32 | + return true |
| 33 | + } catch (e) { |
| 34 | + return false |
12 | 35 | } |
13 | 36 |
|
14 | | - return dotSplit.reduce((acc, currElem) => acc && isBase64(currElem, { urlSafe: true }), true); |
15 | 37 | } |
0 commit comments