Skip to content

Commit

Permalink
feat: add Date as valid input to timestamp setting functions
Browse files Browse the repository at this point in the history
  • Loading branch information
panva committed Oct 23, 2023
1 parent 4dd4f05 commit bd830a4
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 7 deletions.
26 changes: 20 additions & 6 deletions src/jwt/produce.ts
Expand Up @@ -3,6 +3,14 @@ import epoch from '../lib/epoch.js'
import isObject from '../lib/is_object.js'
import secs from '../lib/secs.js'

function validateInput(label: string, input: number) {
if (!Number.isFinite(input)) {
throw new TypeError(`Invalid ${label} input`)
}

return input
}

/** Generic class for JWT producing. */
export class ProduceJWT {
protected _payload!: JWTPayload
Expand Down Expand Up @@ -62,9 +70,11 @@ export class ProduceJWT {
* that is used as a value, when string is passed it is resolved to a time span and added to the
* current timestamp.
*/
setNotBefore(input: number | string) {
setNotBefore(input: number | string | Date) {
if (typeof input === 'number') {
this._payload = { ...this._payload, nbf: input }
this._payload = { ...this._payload, nbf: validateInput('setNotBefore', input) }
} else if (input instanceof Date) {
this._payload = { ...this._payload, nbf: validateInput('setNotBefore', epoch(input)) }
} else {
this._payload = { ...this._payload, nbf: epoch(new Date()) + secs(input) }
}
Expand All @@ -78,9 +88,11 @@ export class ProduceJWT {
* passed that is used as a value, when string is passed it is resolved to a time span and added
* to the current timestamp.
*/
setExpirationTime(input: number | string) {
setExpirationTime(input: number | string | Date) {
if (typeof input === 'number') {
this._payload = { ...this._payload, exp: input }
this._payload = { ...this._payload, exp: validateInput('setExpirationTime', input) }
} else if (input instanceof Date) {
this._payload = { ...this._payload, exp: validateInput('setExpirationTime', epoch(input)) }
} else {
this._payload = { ...this._payload, exp: epoch(new Date()) + secs(input) }
}
Expand All @@ -93,11 +105,13 @@ export class ProduceJWT {
* @param input "iat" (Issued At) Claim value to set on the JWT Claims Set. Default is current
* timestamp.
*/
setIssuedAt(input?: number) {
setIssuedAt(input?: number | Date) {
if (typeof input === 'undefined') {
this._payload = { ...this._payload, iat: epoch(new Date()) }
} else if (input instanceof Date) {
this._payload = { ...this._payload, iat: validateInput('setIssuedAt', epoch(input)) }
} else {
this._payload = { ...this._payload, iat: input }
this._payload = { ...this._payload, iat: validateInput('setIssuedAt', input) }
}
return this
}
Expand Down
5 changes: 4 additions & 1 deletion test/jwt/sign.test.mjs
Expand Up @@ -101,15 +101,18 @@ async function testJWTsetFunction(t, method, claim, value, expected = value) {
t.is(claims[claim], expected)
}
testJWTsetFunction.title = (title, method, claim, value) =>
`SignJWT.prototype.${method} called with ${value}`
`SignJWT.prototype.${method} called with ${value?.constructor?.name || typeof value}`

test(testJWTsetFunction, 'setIssuer', 'iss', 'urn:example:issuer')
test(testJWTsetFunction, 'setSubject', 'sub', 'urn:example:subject')
test(testJWTsetFunction, 'setAudience', 'aud', 'urn:example:audience')
test(testJWTsetFunction, 'setJti', 'jti', 'urn:example:jti')
test(testJWTsetFunction, 'setIssuedAt', 'iat', 0)
test(testJWTsetFunction, 'setIssuedAt', 'iat', undefined, now)
test(testJWTsetFunction, 'setIssuedAt', 'iat', new Date(now * 1000), now)
test(testJWTsetFunction, 'setExpirationTime', 'exp', 0)
test(testJWTsetFunction, 'setExpirationTime', 'exp', '10s', now + 10)
test(testJWTsetFunction, 'setExpirationTime', 'exp', new Date(now * 1000), now)
test(testJWTsetFunction, 'setNotBefore', 'nbf', 0)
test(testJWTsetFunction, 'setNotBefore', 'nbf', '10s', now + 10)
test(testJWTsetFunction, 'setNotBefore', 'nbf', new Date(now * 1000), now)

0 comments on commit bd830a4

Please sign in to comment.