@tsndr/cloudflare-worker-jwt
Advanced tools
Comparing version 1.0.8 to 1.1.0
58
index.js
@@ -29,5 +29,24 @@ class Base64URL { | ||
} | ||
utf8ToUint8Array(str) { | ||
_utf8ToUint8Array(str) { | ||
return Base64URL.parse(btoa(unescape(encodeURIComponent(str)))) | ||
} | ||
_decodePayload(raw) { | ||
switch (raw.length % 4) { | ||
case 0: | ||
break | ||
case 2: | ||
raw += '==' | ||
break | ||
case 3: | ||
raw += '=' | ||
break | ||
default: | ||
throw new Error('Illegal base64url string!') | ||
} | ||
try { | ||
return JSON.parse(decodeURIComponent(escape(atob(raw)))) | ||
} catch { | ||
return null | ||
} | ||
} | ||
async sign(payload, secret, algorithm = 'HS256') { | ||
@@ -43,7 +62,8 @@ if (payload === null || typeof payload !== 'object') | ||
throw new Error('algorithm not found') | ||
payload.iat = Math.floor(Date.now() / 1000) | ||
const payloadAsJSON = JSON.stringify(payload) | ||
const partialToken = `${Base64URL.stringify(this.utf8ToUint8Array(JSON.stringify({ alg: algorithm, typ: 'JWT' })))}.${Base64URL.stringify(this.utf8ToUint8Array(payloadAsJSON))}` | ||
const key = await crypto.subtle.importKey('raw', this.utf8ToUint8Array(secret), importAlgorithm, false, ['sign']) | ||
const partialToken = `${Base64URL.stringify(this._utf8ToUint8Array(JSON.stringify({ alg: algorithm, typ: 'JWT' })))}.${Base64URL.stringify(this._utf8ToUint8Array(payloadAsJSON))}` | ||
const key = await crypto.subtle.importKey('raw', this._utf8ToUint8Array(secret), importAlgorithm, false, ['sign']) | ||
const characters = payloadAsJSON.split('') | ||
const it = this.utf8ToUint8Array(payloadAsJSON).entries() | ||
const it = this._utf8ToUint8Array(payloadAsJSON).entries() | ||
let i = 0 | ||
@@ -56,3 +76,3 @@ const result = [] | ||
} | ||
const signature = await crypto.subtle.sign(importAlgorithm.name, key, this.utf8ToUint8Array(partialToken)) | ||
const signature = await crypto.subtle.sign(importAlgorithm.name, key, this._utf8ToUint8Array(partialToken)) | ||
return `${partialToken}.${Base64URL.stringify(new Uint8Array(signature))}` | ||
@@ -73,7 +93,12 @@ } | ||
throw new Error('algorithm not found') | ||
const keyData = this.utf8ToUint8Array(secret) | ||
const keyData = this._utf8ToUint8Array(secret) | ||
const key = await crypto.subtle.importKey('raw', keyData, importAlgorithm, false, ['sign']) | ||
const partialToken = tokenParts.slice(0, 2).join('.') | ||
const payload = this._decodePayload(tokenParts[1].replace(/-/g, '+').replace(/_/g, '/')) | ||
if (payload.nbf && payload.nbf >= Math.floor(Date.now() / 1000)) | ||
return false | ||
if (payload.exp && payload.exp < Math.floor(Date.now() / 1000)) | ||
return false | ||
const signaturePart = tokenParts[2] | ||
const messageAsUint8Array = this.utf8ToUint8Array(partialToken) | ||
const messageAsUint8Array = this._utf8ToUint8Array(partialToken) | ||
const res = await crypto.subtle.sign(importAlgorithm.name, key, messageAsUint8Array) | ||
@@ -83,20 +108,3 @@ return Base64URL.stringify(new Uint8Array(res)) === signaturePart | ||
decode(token) { | ||
let output = token.split('.')[1].replace(/-/g, '+').replace(/_/g, '/') | ||
switch (output.length % 4) { | ||
case 0: | ||
break | ||
case 2: | ||
output += '==' | ||
break | ||
case 3: | ||
output += '=' | ||
break | ||
default: | ||
throw new Error('Illegal base64url string!') | ||
} | ||
try { | ||
return JSON.parse(decodeURIComponent(escape(atob(output)))) | ||
} catch { | ||
return null | ||
} | ||
return this._decodePayload(token.split('.')[1].replace(/-/g, '+').replace(/_/g, '/')) | ||
} | ||
@@ -103,0 +111,0 @@ } |
{ | ||
"name": "@tsndr/cloudflare-worker-jwt", | ||
"version": "1.0.8", | ||
"version": "1.1.0", | ||
"description": "A lightweight JWT implementation with ZERO dependencies for Cloudflare Worker", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -9,2 +9,3 @@ # Cloudflare Worker JWT | ||
- [Usage](#usage) | ||
- [Examples](#examples) | ||
@@ -19,18 +20,2 @@ ## Install | ||
### Simple Example | ||
```javascript | ||
const jwt = require('@tsndr/cloudflare-worker-jwt') | ||
// Creating a token | ||
const token = jwt.sign({ name: 'John Doe', email: 'john.doe@gmail.com' }, 'secret') | ||
// Verifing token | ||
const isValid = jwt.verify(token, 'secret') | ||
// Decoding token | ||
const payload = jwt.decode(token) | ||
``` | ||
<hr> | ||
@@ -46,3 +31,3 @@ | ||
----------- | -------- | -------- | ------- | ----------- | ||
`payload` | `object` | required | - | The payload object | ||
`payload` | `object` | required | - | The payload object. To use `nbf` (Not Before) and/or `exp` (Expiration Time) add `nbf` and/or `exp` to the payload. | ||
`secret` | `string` | required | - | A string which is used to sign the payload. | ||
@@ -67,3 +52,3 @@ `algorithm` | `string` | optional | `HS256` | The algorithm used to sign the payload, possible values: `HS256` or `HS512` | ||
#### `return` | ||
returns `boolean` | ||
Returns `true` if signature, `nbf` (if set) and `exp` (if set) are valid, otherwise returns `false`. | ||
@@ -74,3 +59,3 @@ <hr> | ||
Returns the payload without verifying the integrity of the token. | ||
Returns the payload **without** verifying the integrity of the token. Please use `jwt.verify()` first to keep your application secure! | ||
@@ -82,2 +67,43 @@ Argument | Type | Satus | Default | Description | ||
#### `return` | ||
returns payload `object` | ||
Returns payload `object`. | ||
## Examples | ||
### Basic Example | ||
```javascript | ||
async () => { | ||
const jwt = require('@tsndr/cloudflare-worker-jwt') | ||
// Creating a token | ||
const token = await jwt.sign({ name: 'John Doe', email: 'john.doe@gmail.com' }, 'secret') | ||
// Verifing token | ||
const isValid = await jwt.verify(token, 'secret') | ||
// Decoding token | ||
const payload = jwt.decode(token) | ||
} | ||
``` | ||
### Restrict Timeframe | ||
```javascript | ||
async () => { | ||
const jwt = require('@tsndr/cloudflare-worker-jwt') | ||
// Creating a token | ||
const token = await jwt.sign({ | ||
name: 'John Doe', | ||
email: 'john.doe@gmail.com', | ||
nbf: Math.floor(Date.now() / 1000) + (60 * 60), // Not before: Now + 1h | ||
exp: Math.floor(Date.now() / 1000) + (2 * (60 * 60)) // Expires: Now + 2h | ||
}, 'secret') | ||
// Verifing token | ||
const isValid = await jwt.verify(token, 'secret') // false | ||
// Decoding token | ||
const payload = jwt.decode(token) // { name: 'John Doe', email: 'john.doe@gmail.com', ... } | ||
} | ||
``` |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
12900
164
103