1
0

Compare commits

...

4 Commits

Author SHA1 Message Date
72e64f1316 2.3.2 2023-11-16 20:34:51 +01:00
e235d835aa add generics to sign 2023-11-16 20:34:27 +01:00
03c66f4223 2.3.1 2023-11-16 20:23:58 +01:00
70488a6a48 update types and add generics to decode 2023-11-16 20:23:43 +01:00
4 changed files with 30 additions and 27 deletions

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "@tsndr/cloudflare-worker-jwt",
"version": "2.3.0",
"version": "2.3.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@tsndr/cloudflare-worker-jwt",
"version": "2.3.0",
"version": "2.3.2",
"license": "MIT",
"devDependencies": {
"@cloudflare/workers-types": "^4.20231025.0",

View File

@@ -1,6 +1,6 @@
{
"name": "@tsndr/cloudflare-worker-jwt",
"version": "2.3.0",
"version": "2.3.2",
"description": "A lightweight JWT implementation with ZERO dependencies for Cloudflare Worker",
"type": "module",
"exports": "./index.js",

View File

@@ -14,6 +14,11 @@ type Data = {
[key in JwtAlgorithm]: Dataset
}
type Payload = {
sub: string
name: string
}
const data: Data = {
'ES256': {
public: '-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEEVs/o5+uQbTjL3chynL4wXgUg2R9\nq9UU8I5mEovUf86QZ7kOBIjJwqnzD1omageEHWwHdBO6B+dFabmdT9POxg==\n-----END PUBLIC KEY-----',
@@ -63,7 +68,7 @@ const data: Data = {
}
const payload = {
const payload: Payload = {
sub: "1234567890",
name: "John Doe",
}
@@ -77,7 +82,7 @@ describe.each(Object.entries(data) as [JwtAlgorithm, Dataset][])('%s', (algorith
})
test('decode external', async () => {
const decoded = jwt.decode(data.token)
const decoded = jwt.decode<Payload>(data.token)
expect({
sub: payload.sub,
name: payload.name
@@ -88,7 +93,7 @@ describe.each(Object.entries(data) as [JwtAlgorithm, Dataset][])('%s', (algorith
})
test('sign internal', async () => {
token = await jwt.sign(payload, data.private, algorithm)
token = await jwt.sign<Payload>(payload, data.private, algorithm)
expect(token).toMatch(/^[a-zA-Z0-9\-_]+\.[a-zA-Z0-9\-_]+\.[a-zA-Z0-9\-_]+$/)
})

View File

@@ -10,7 +10,7 @@ export type JwtAlgorithm = 'ES256'|'ES384'|'ES512'|'HS256'|'HS384'|'HS512'|'RS25
/**
* @typedef JwtAlgorithms
*/
export interface JwtAlgorithms {
export type JwtAlgorithms = {
[key: string]: SubtleCryptoImportKeyAlgorithm
}
@@ -18,16 +18,14 @@ export interface JwtAlgorithms {
* @typedef JwtHeader
* @prop {string} [typ] Type
*/
export interface JwtHeader {
export type JwtHeader<T = {}> = {
/**
* Type (default: `"JWT"`)
*
* @default "JWT"
*/
typ?: string
[key: string]: any
}
} & T
/**
* @typedef JwtPayload
@@ -39,7 +37,7 @@ export interface JwtHeader {
* @prop {string} [iat] Issued At
* @prop {string} [jti] JWT ID
*/
export interface JwtPayload {
export type JwtPayload<T = {}> = {
/** Issuer */
iss?: string
@@ -62,13 +60,13 @@ export interface JwtPayload {
jti?: string
[key: string]: any
}
} & T
/**
* @typedef JwtOptions
* @prop {JwtAlgorithm | string} algorithm
*/
export interface JwtOptions {
export type JwtOptions = {
algorithm?: JwtAlgorithm | string
}
@@ -77,32 +75,32 @@ export interface JwtOptions {
* @extends JwtOptions
* @prop {JwtHeader} [header]
*/
export interface JwtSignOptions extends JwtOptions {
export type JwtSignOptions = {
header?: JwtHeader
}
} & JwtOptions
/**
* @typedef JwtVerifyOptions
* @extends JwtOptions
* @prop {boolean} [throwError=false] If `true` throw error if checks fail. (default: `false`)
*/
export interface JwtVerifyOptions extends JwtOptions {
export type JwtVerifyOptions = {
/**
* If `true` throw error if checks fail. (default: `false`)
*
* @default false
*/
throwError?: boolean
}
} & JwtOptions
/**
* @typedef JwtData
* @prop {JwtHeader} header
* @prop {JwtPayload} payload
*/
export interface JwtData {
header?: JwtHeader
payload?: JwtPayload
export type JwtData<Payload = {}, Header = {}> = {
header?: JwtHeader<Header>
payload?: JwtPayload<Payload>
}
const algorithms: JwtAlgorithms = {
@@ -215,7 +213,7 @@ function decodePayload<T = any>(raw: string): T | undefined {
* @throws {Error} If there's a validation issue.
* @returns {Promise<string>} Returns token as a `string`.
*/
export async function sign(payload: JwtPayload, secret: string | JsonWebKey, options: JwtSignOptions | JwtAlgorithm = 'HS256'): Promise<string> {
export async function sign<Payload = {}>(payload: JwtPayload<Payload>, secret: string | JsonWebKey, options: JwtSignOptions | JwtAlgorithm = 'HS256'): Promise<string> {
if (typeof options === 'string')
options = { algorithm: options }
@@ -309,10 +307,10 @@ export async function verify(token: string, secret: string | JsonWebKey, options
* @param {string} token The token string generated by `jwt.sign()`.
* @returns {JwtData} Returns an `object` containing `header` and `payload`.
*/
export function decode(token: string): JwtData {
export function decode<Payload = {}, Header = {}>(token: string): JwtData<Payload, Header> {
return {
header: decodePayload<JwtHeader>(token.split('.')[0].replace(/-/g, '+').replace(/_/g, '/')),
payload: decodePayload<JwtPayload>(token.split('.')[1].replace(/-/g, '+').replace(/_/g, '/'))
header: decodePayload<JwtHeader<Header>>(token.split('.')[0].replace(/-/g, '+').replace(/_/g, '/')),
payload: decodePayload<JwtPayload<Payload>>(token.split('.')[1].replace(/-/g, '+').replace(/_/g, '/'))
}
}