Skip to content

Commit

Permalink
Init
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelzoidl committed May 5, 2017
1 parent f73ea06 commit d3282d5
Show file tree
Hide file tree
Showing 8 changed files with 3,208 additions and 2 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# Custom
build

# macOS
.DS_Store

# Logs
logs
*.log
Expand Down
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
language: node_js
node_js:
- "6.9.5"
after_success: npm run coverage
39 changes: 37 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,37 @@
# jwt-valid
Validates a passed JWT token based on the RFC 7519 standard
# JWT Valid
> Pass a JWT token and get a boolean if the token is valid, the requirements for a valid token are defined by the official [RFC 7519 standard](https://tools.ietf.org/html/rfc7519)
[![Zero Dependencies](https://img.shields.io/badge/zero-dependencies-brightgreen.svg)]()
[![Coverage Status](https://coveralls.io/repos/github/entwicklerstube/jwt-valid/badge.svg?branch=master)](https://coveralls.io/github/entwicklerstube/jwt-valid?branch=master)
[![Build Status](https://travis-ci.org/entwicklerstube/jwt-valid.svg?branch=master)](https://travis-ci.org/entwicklerstube/jwt-valid)
[![devDependencies Status](https://david-dm.org/entwicklerstube/jwt-valid/dev-status.svg)](https://david-dm.org/entwicklerstube/jwt-valid?type=dev)
[![greenkeeper badge](https://badges.greenkeeper.io/entwicklerstube/jwt-valid.svg)](https://greenkeeper.io/)

### Install
**npm**
```
npm install jwt-valid
```

**yarn**
```
yarn add jwt-valid
```

### Usage
```js
jwtValid(JWT_TOKEN<STRING>)
```

### Example
```js
jwtValid('this is no valid token') // returns false
jwtValid('some.valid.token') // returns true
```

### Support
**Browser**
Under the hood it uses the `window.atob()` native feature which is supported in each major browser and IE from version 10 ([`check mozilla dev site`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/atob#Browser_compatibility))

**Node**
Uses the native `Buffer` API from node ([`check node documentation`](https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings))
33 changes: 33 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
export const parseBase64ByPlattform = base64String => {
if (!base64String || !isValidBase64(base64String)) throw new Error('No valid base64 passed')

if(typeof window === 'undefined' && (process && process.version !== 'undefined')) {
return Buffer.from(base64String, 'base64').toString()
} else {
return window.atob(base64String)
}
}

export const isValidBase64 = base64String => {
if (!base64String) return false
if (!(/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(base64String))) return false

return true
}

export const parseJwtToken = jwtToken => {
if(!jwtToken) throw new Error('No valid JWT token passed')

const jwtTokenParts = jwtToken.split('.')
if(jwtTokenParts.length !== 3) throw new Error('No valid JWT token passed')

try {
const header = JSON.parse(parseBase64ByPlattform(jwtTokenParts[0]))
const payload = JSON.parse(parseBase64ByPlattform(jwtTokenParts[1]))
const signature = jwtTokenParts[2]

return { header, payload, signature }
} catch (err) {
throw new Error('No valid JWT token passed')
}
}
4 changes: 4 additions & 0 deletions mocha.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import chai from 'chai'

global.chai = chai
global.expect = chai.expect
52 changes: 52 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"name": "jwt-valid",
"version": "1.0.0",
"description": "Pass a jwt token and get a boolean if the token is valid",
"keywords": "jwt, jwt valid, jwt still valid, valid, valid",
"main": "build/index.js",
"repository": "https://github.com/entwicklerstube/jwt-valid",
"author": "Michael J. Zoidl",
"license": "MIT",
"scripts": {
"build": "rimraf build && mkdir build && babel index.js --out-dir build",
"prepublish": "yarn run standard && yarn run test && yarn run build",
"test": "mocha test.js --require mocha --compilers js:babel-core/register",
"standard": "standard --env mocha",
"nyc": "nyc --require babel-core/register --require './mocha.js' mocha test.js",
"coverage": "yarn run nyc && nyc report --reporter=text-lcov | coveralls",
"prepublish": "yarn run test && yarn run build"
},
"files": [
"build"
],
"babel": {
"presets": [
"es2015"
]
},
"standard": {
"ignore": [
"build"
],
"globals": [
"expect"
]
},
"nyc": {
"exclude": [
"build",
"test.js",
"mocha.js"
]
},
"devDependencies": {
"babel-cli": "^6.24.0",
"babel-preset-es2015": "^6.24.0",
"chai": "^3.5.0",
"mocha": "^3.2.0",
"nyc": "^10.1.2",
"rimraf": "^2.6.1",
"standard": "^9.0.2",
"coveralls": "^2.12.0"
}
}
67 changes: 67 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import jwtValid, { parseBase64ByPlattform, isValidBase64, parseJwtToken } from './index'

const jwtToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqd3QiOiJpcyBhd2Vzb21lISJ9.j8Z3twgi5nCrZJXH1JoxfQ8q1u5btwr3vS3wyqfytOo'

describe('JWT Valid', () => {
describe('isValidBase64', () => {
it('returns false if a not valid base64 string is passed', () => {
expect(isValidBase64('No Valid Base64 String')).to.be.false
})

it('returns true if a valid base64 string is passed', () => {
expect(isValidBase64('SSBhbSB2YWxpZA==')).to.be.true
})
})

describe('parseBase64ByPlattform', () => {
it('returns error if no valid token is passed', () => {
expect(() => parseBase64ByPlattform()).to.throw('No valid base64 passed')
})

it('returns encoded base64 string', () => {
expect(parseBase64ByPlattform('SGVsbG8gV29ybGQ=')).to.equal('Hello World')
})
})

describe('parseJwtToken', () => {
it('returns error if nothing is passed', () => {
expect(() => parseJwtToken()).to.throw('No valid JWT token passed')
})

it('returns error if no valid token is passed', () => {
expect(() => parseJwtToken('iam-no-jwt-token')).to.throw('No valid JWT token passed')
})

it('returns error if no valid token is passed', () => {
expect(() => parseJwtToken('a.b.c')).to.throw('No valid JWT token passed')
})

it('returns error if no valid token is passed', () => {
expect(() => parseJwtToken('SGVsbG8gV29ybGQ=.SGVsbG8gV29ybGQ=.foobar')).to.throw('No valid JWT token passed')
})

it('returns error if no valid token is passed', () => {
expect(() => parseJwtToken('eyJhbGciOiJpbnZhbGlkIiwidHlwIjoiaW52YWxpZCJ9.eyBub3RoaW5nOiAndHJ1ZScgfQ==.some_signature')).to.throw('No valid JWT token passed')
})

it('returns a object', () => {
expect(parseJwtToken(jwtToken)).to.be.a('object')
})

it('returns a object with the props header, payload and signature', () => {
expect(parseJwtToken(jwtToken)).to.include.keys('header', 'payload', 'signature')
})

it('returns a object with the header containing the decoded informations', () => {
expect(parseJwtToken(jwtToken).header).to.deep.equal({ alg: 'HS256', typ: 'JWT' })
})

it('returns a object with the payload containing the decoded informations', () => {
expect(parseJwtToken(jwtToken).payload).to.deep.equal({ jwt: 'is awesome!' })
})

it('returns a object with the signature string', () => {
expect(parseJwtToken(jwtToken).signature).to.equal(jwtToken.split('.')[2])
})
})
})
Loading

0 comments on commit d3282d5

Please sign in to comment.