Skip to content

Commit

Permalink
feat: allow creating tokens without expiration date
Browse files Browse the repository at this point in the history
  • Loading branch information
lhermann committed Nov 13, 2023
1 parent cb9aa8d commit 7734e8e
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 24 deletions.
24 changes: 11 additions & 13 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ const jwt = require('jsonwebtoken')

/**
* type ParsedToken = TokenPayload & {
* iat: Date
* exp: Date
* iat: Date | null
* exp: Date | null
* isValid: boolean
* }
*/
Expand All @@ -17,16 +17,14 @@ const jwt = require('jsonwebtoken')
*
* @param {TokenPayload} payload - The payload to be signed.
* @param {string} privateKey - The private key used for signing the token.
* @param {string|Date} expiresIn - The duration for which the token is valid (default is '1 month').
* @param {string|Date|null} expiresIn - The duration for which the token is valid (default is '1 month').
* @return {string} - The signed JWT.
*/
function signToken (payload, privateKey, expiresIn = '1m') {
if (expiresIn instanceof Date ) expiresIn = Math.floor((expiresIn.getTime() - Date.now()) / 1000)
return jwt.sign(
payload,
_parseKey(privateKey),
{ algorithm: 'RS256', expiresIn },
)
function signToken (payload, privateKey, expiresIn = null) {
const options = { algorithm: 'RS256' }
if (expiresIn instanceof Date ) options.expiresIn = Math.floor((expiresIn.getTime() - Date.now()) / 1000)
if (typeof expiresIn === 'string') options.expiresIn = expiresIn
return jwt.sign(payload, _parseKey(privateKey), options)
}

/**
Expand All @@ -37,9 +35,9 @@ function signToken (payload, privateKey, expiresIn = '1m') {
*/
function parseToken (tokenString, publicKey) {
const parsed = jwt.verify(tokenString, _parseKey(publicKey), { algorithms: ['RS256'], ignoreExpiration: true })
parsed.exp = new Date(parsed.exp * 1000)
parsed.iat = new Date(parsed.iat * 1000)
parsed.isValid = new Date() <= parsed.exp
parsed.exp = parsed.exp ? new Date(parsed.exp * 1000) : null
parsed.iat = parsed.iat ? new Date(parsed.iat * 1000) : null
parsed.isValid = parsed.exp === null || new Date() <= parsed.exp
return parsed
}

Expand Down
39 changes: 28 additions & 11 deletions tests/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,25 @@ vceYTMfN
})

describe('signToken', () => {
const activeUntil = new Date(new Date().setMonth(new Date().getMonth() + -1))
const samplePayload = {
n: 'Pro',
img: 'ic-pro-plan.png',
lim: { s: 4, l: 2, r: -1, d: 20, t: 50, m: 50 },
prm: ['LICENSED', 'API_ACCESS'],
t: 'MYNK9OdTESfbLPaj8ioA95cWFAt1',
}

test('sign payload', () => {
const token = signToken(samplePayload, JWT_PRIVATE_KEY, activeUntil)
test('sign with future date', () => {
const future = new Date(new Date().setMonth(new Date().getMonth() + 1))
const token = signToken({ foo: 'bar' }, JWT_PRIVATE_KEY, future)
expect(typeof token).to.equal('string')
})

test('sign with past date', () => {
const past = new Date(new Date().setMonth(new Date().getMonth() - 1))
const token = signToken({ foo: 'bar' }, JWT_PRIVATE_KEY, past)
expect(typeof token).to.equal('string')
})

test('sign with null date', () => {
const token = signToken({ foo: 'bar' }, JWT_PRIVATE_KEY, null)
expect(typeof token).to.equal('string')
})

test('sign without date', () => {
const token = signToken({ foo: 'bar' }, JWT_PRIVATE_KEY)
expect(typeof token).to.equal('string')
})
})
Expand All @@ -88,6 +96,15 @@ describe('parseToken', () => {
expect(parsedToken.isValid).to.equal(false)
})

test('parse token without expiration date', () => {
const token = signToken({ foo: 'bar' }, JWT_PRIVATE_KEY, null)
const parsedToken = parseToken(token, JWT_PUBLIC_KEY)
expect(typeof parsedToken).to.equal('object')
expect(parsedToken.foo).to.equal('bar')
expect(parsedToken.exp).to.equal(null)
expect(parsedToken.isValid).to.equal(true)
})

test('parse token with invalid signature', () => {
const token = signToken({ foo: 'bar' }, JWT_PRIVATE_KEY)
const fn = () => parseToken(token + 'XXX', JWT_PUBLIC_KEY)
Expand Down

0 comments on commit 7734e8e

Please sign in to comment.