Giter Club home page Giter Club logo

jose's Introduction

jose

jose is JavaScript module for JSON Object Signing and Encryption, providing support for JSON Web Tokens (JWT), JSON Web Signature (JWS), JSON Web Encryption (JWE), JSON Web Key (JWK), JSON Web Key Set (JWKS), and more. The module is designed to work across various Web-interoperable runtimes including Node.js, browsers, Cloudflare Workers, Deno, Bun, and others.

Support from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by becoming a sponsor.

Dependencies: 0

jose has no dependencies and it exports tree-shakeable ESM. CJS is also supported.

Documentation

jose is distributed via npmjs.com, deno.land/x, cdnjs.com, jsdelivr.com, and github.com.

example ESM import

import * as jose from 'jose'

example CJS require

const jose = require('jose')

JSON Web Tokens (JWT)

The jose module supports JSON Web Tokens (JWT) and provides functionality for signing and verifying tokens, as well as their JWT Claims Set validation.

Encrypted JSON Web Tokens

The jose module supports encrypted JSON Web Tokens and provides functionality for encrypting and decrypting tokens, as well as their JWT Claims Set validation.

Key Utilities

The jose module supports importing, exporting, and generating keys and secrets in various formats, including PEM formats like SPKI, X.509 certificate, and PKCS #8, as well as JSON Web Key (JWK).

JSON Web Signature (JWS)

The jose module supports signing and verification of JWS messages with arbitrary payloads in Compact, Flattened JSON, and General JSON serialization syntaxes.

JSON Web Encryption (JWE)

The jose module supports encryption and decryption of JWE messages with arbitrary plaintext in Compact, Flattened JSON, and General JSON serialization syntaxes.

Other

The following are additional features and utilities provided by the jose module:

Implemented specifications

The jose module implements the following specifications:

  • JSON Web Signature (JWS) - RFC7515
  • JSON Web Encryption (JWE) - RFC7516
  • JSON Web Key (JWK) - RFC7517
  • JSON Web Algorithms (JWA) - RFC7518
  • JSON Web Token (JWT) - RFC7519
  • JSON Web Key Thumbprint - RFC7638
  • JSON Web Key Thumbprint URI - RFC9278
  • JWS Unencoded Payload Option - RFC7797
  • CFRG Elliptic Curve ECDH and Signatures - RFC8037
  • secp256k1 EC Key curve support - RFC8812

The algorithm implementations have been tested using test vectors from their respective specifications as well as RFC7520.

Supported Runtimes

The jose module is compatible with JavaScript runtimes that support the utilized Web API globals and standard built-in objects or are Node.js.

The following runtimes are supported (this is not an exhaustive list):

Please note that certain algorithms may not be available depending on the runtime used. You can find a list of available algorithms for each runtime in the specific issue links provided above.

Supported Versions

Version Security Fixes ๐Ÿ”‘ Other Bug Fixes ๐Ÿž New Features โญ
v5.x โœ… โœ… โœ…
v4.x โœ… โŒ โŒ
v2.x โœ… โŒ โŒ

jose's People

Contributors

alchar avatar alexsey avatar beorn247 avatar bespokebob avatar big-kahuna-burger avatar codedust avatar codyebberson avatar danbulant avatar dependabot[bot] avatar desjoerd avatar eevleevs avatar ekosz avatar evan361425 avatar flaviostutz avatar ghdoergeloh avatar github-actions[bot] avatar githubpang avatar hannesvdvreken avatar italypaleale avatar jahands avatar kdenhartog avatar lboynton avatar lizthegrey avatar maxarndt avatar maximivanov avatar nek- avatar panva avatar richpryce avatar rolandzwaga avatar trebler avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jose's Issues

bug: KeyStore.toJWKS(true) crashed if keystore includes some public keys

Describe the bug

If the KeyStore instance includes at least one public key then .toJWKS(true) would throw an error public key cannot be exported as private

To Reproduce

const jose = require('@panva/jose')

const privateKey = `-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp
wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5
1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh
3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2
pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il
AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF
L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k
X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
-----END RSA PRIVATE KEY-----`

const publicKey = `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0
FPqri0cb2JZfXJ/DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/
3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQAB
-----END PUBLIC KEY-----`

const store = new jose.JWKS.KeyStore

store.add(jose.JWK.asKey(privateKey))
store.add(jose.JWK.asKey(publicKey))

console.log(store.toJWKS(true))

Expected behaviour
It should be stringified with one private and one public key (preferable)
OR
Key Store should not allow adding both private and public key at the same time

Environment:

  • @panva/jose version: [1.9.1]
  • node version: [e.g. v12.10.0]

Additional context
Add any other context about the problem here.

  • the bug is happening on latest @panva/jose too.
  • i have searched the issues tracker on github for similar issues and couldn't find anything related.

bug: node v11.x signature verification failed

Description
JWT token verification with RS256 fails even though all the keys are in order. The exception is JWSVerificationFailed: signature verification failed.

I tracked down the problem to the files key_object.js and rsassa.js. The first one contains a polyfill for the KeyObject class, however the polyfill also defines an extra method asInput(). Then the second file uses this method. However starting with Node version 11.13.0 the native KeyObject is exported and the polyfill isn't used anymore. This causes the call to asInput() to fail in rsassa.js since the method doesn't exist on the native object.

Environment:

  • jose version: 1.9.2
  • node version: 11.13.0 and above (I triggered this on 11.16)

Compile error

Using this library, on compiling it use my ย tsconfig to compile the library,
So I can't compile it because of some errors:

node_modules/jose/src/jwk/parse.ts:80:5 - error TS7029: Fallthrough case in switch.

80     case 'RSA':
       ~~~~~~~~~~~


Found 1 error.

Even more if I enable the new TS flag noUncheckedIndexedAccess.

bug:

Describe the bug

I just installed oidc-provider and am attempting to use it. That package has this package, @panva/jose as a dependency. When I attempt to run my project, I am getting this error:

Uncaught Exception! /node_modules/@panva/jose/lib/jwe/encrypt.js:21
  #aad
  ^

SyntaxError: Invalid or unexpected token
    at new Script (vm.js:73:7)
    at createScript (vm.js:245:10)
    at Object.runInThisContext (vm.js:297:10)
    at Module._compile (internal/modules/cjs/loader.js:657:28)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)
    at Module.require (internal/modules/cjs/loader.js:637:17)
    at require (internal/modules/cjs/helpers.js:20:18)

The invalid characters appear to be in the source code: https://github.com/panva/jose/blob/master/lib/jwe/encrypt.js#L21 Seems like a mistake that # characters ended up in the source code. However, if the # characters are supposed to be there, how do you recommend proceeding?

To Reproduce

Steps to reproduce the behaviour:

  1. npm i oidc-provider.
  2. Note that @panva/jose version 1.6.1 was installed as a dependency. node_modules/@panva/jose/package.json
  3. Attempt to run your project using oidc-provider.
  4. Note that there is a runtime error.
  5. Look in node_modules/@panva/jose/lib/jwe/encrypt.js and find # character in many places.
  6. Also note that the # character has been committed into the source code. https://github.com/panva/jose/blob/master/lib/jwe/encrypt.js#L21

Expected behaviour
I expected the code to run. ๐Ÿ˜„

Environment:

  • @panva/jose version: 1.6.1
  • node version: 10.9.0

Additional context
Add any other context about the problem here.

  • the bug is happening on latest @panva/jose too.
  • i have searched the issues tracker on github for similar issues and couldn't find anything related.

Typescript JWK Key return type issues

Describe the bug
Currently all return values regarding Keys are typed under the Key interface.

This causes that no Key type specific parameters can be accessed (for example EC Key crv value) in the return values regarding keys.

*To Reproduce

// fill with EC type public / private key
const ecTypeKey = 'EC KEY';
const key = JWK.asKey(ecTypeKey);
// This will cause an error: Property 'crv' does not exist on type 'Key'.
console.log(key.crv);

Expected behaviour
Should return proper Key sub type, so parameters can be accessed

Environment:

  • jose version: [e.g. v1.22.2]
  • node version: [e.g. v13.3.0]

Additional context

  • This should be implemented to all return values regarding Key type (JWE.completeDecrypt, etc)

bug: TypeError: The "original" argument must be of type Function

Get error on

import {Issuer} from 'openid-client';


TypeError: The "original" argument must be of type Function
promisify

GoogleApi.Tester/GoogleApi.Tester/ClientApp/node_modules/util/util.js:605
602 | var kCustomPromisifiedSymbol = typeof Symbol !== 'undefined' ? Symbol('util.promisify.custom') : undefined;
603 |
604 | exports.promisify = function promisify(original) {

605 | if (typeof original !== 'function') throw new TypeError('The "original" argument must be of type Function');
606 |
607 | if (kCustomPromisifiedSymbol && original[kCustomPromisifiedSymbol]) {
608 | var fn = original[kCustomPromisifiedSymbol];
View compiled
(anonymous function)

GoogleApi.Tester/GoogleApi.Tester/ClientApp/node_modules/jose/lib/jwk/key/rsa.js:44
41 |
42 | var Key = require('./base');
43 |

44 | var generateKeyPair = promisify(async);
45 | var SIG_ALGS = ['PS256', 'RS256', 'PS384', 'RS384', 'PS512', 'RS512'];
46 | var WRAP_ALGS = ['RSA-OAEP', 'RSA1_5'];
47 |
View compiled

Type checking error for generate function

Describe the bug

TypeScript error: Argument of type '"string"' is not assignable to parameter of type '"oct"'

To Reproduce

Steps to reproduce the behaviour:

  1. create a keystore with new jose.JWT.KeyStore()
  2. create a type alias type Algorithm = "RSA" | "EC" | "OKP" | "oct";
  3. create a function generateKey:
function generateKey(alg: Algorithm) {
  return keystore.generateSync(alg, "P-256");
}

Reproduction link: https://codesandbox.io/s/laughing-shockley-hlpr1?file=/src/index.ts

Expected behaviour
Expect no error with type checking

Environment:

  • jose version: v1.26.0
  • node version: v12.13.1

Additional context
Add any other context about the problem here.

  • the bug is happening on latest jose too.
  • i have searched the issues tracker on github for similar issues and couldn't find anything related.

Node crypto blocks the event loop

Is your feature proposal related to a problem? Please describe.
Unfortunately node crypto operations block the event loop. We use signed JWTs for internal service authentication and end up signing thousands of JWTs. For performance, we've had to fork and write our own JWT library simply to offload the crypto operations to separate threads in Node JS using https://github.com/ronomon/crypto-async.

To assist this work I contributed back the RSA sign and verify functions to the crypto-async library: ronomon/crypto-async#7

Describe the solution you'd like
A library such as crypto-async is definitely not something ready for every use case. However, I'd like the option to utilize it with this library. Specifically, I'm simply looking for extension points so that I can use a custom crypto library.

Describe alternatives you've considered
Because the node native crypto operations are blocking, there are very few options. I'd rather contribute to a standards based open source library that supports this than maintain my own.

Additional context
While guidance would be needed on the correct approach, I'd be willing to do the work to add this feature.

  • i have searched the configuration section for this feature and couldn't find it
  • i have searched the issues tracker on github for similar requests and couldn't find anything related.

question: PS256 signatures fail to validate in jwt.io

Hello, I have come to your library specifically looking to generate signatures with the PS256 alg. I am coming from a different lib that may possibly using the same underlying crypto but as this lib requires node >=11 I was hopeful it would resolve the apparent issue I am facing.

The problem I have is that our recipients are failing verification when we have signed with PS256. I'm using jwt.io as an independent source of verification but I can't seem to generate a signature that will pass validation. I'm not sure what jwt.io are using on the backend but whatever it is, I am at a loss.

I've tried using my own private cert as well as using a generated key with pem extraction

       import { JWK, JWS } from "@panva/jose";
       import moment = require("moment");
       const jwkToPem = require("jwk-to-pem");

       const key = await JWK.generate("RSA", 512, { use: "sig"});
       const payload = { foo: "baz", exp: Math.round(moment.now() / 1000 + 3600) };
       const pPem = jwkToPem(key);

       const sig = JWS.sign(payload, key, {alg: "PS256"});
       // resultant sig does not validate in jwt.io

I respect this may simply be an issue with jwt.io but as my recipient is rejecting my signatures I am wondering if there is a more subtle issue at hand or if I am just doing something completely wrong.
Any ideas?

example: Nested signed and encrypted JSON Web Token (JWT)

Producing a nested JWT

import { importJWK, SignJWT, CompactEncrypt } from 'jose'

const encode = TextEncoder.prototype.encode.bind(new TextEncoder());

const jwk = {
  crv: 'P-256',
  x: 'FM3c0AK77LZbxb2LCmUI-Y83DpX04HfakfD1fgfaMVw',
  y: 'fw7dMgz5uHqxbAaYUwgz0IarSIXfkGFP0qTDyC_rkx0',
  d: 'VOh1aBPFq8f1nLh-wQzp5B1WglsJZyhhlUeUWIOZ3mc',
  kty: 'EC',
  kid: 'd2bwmrR5AoI9A0FgNTFxtcNyTPlQTinRxuXUG9uOOWY',
}

const privateKey = await importJWK(jwk, 'ES256')

// Create a signed JWT
const jwt = await new SignJWT({})
  .setSubject('alice')
  .setIssuedAt()
  .setIssuer('https://op.example.com')
  .setProtectedHeader({
    alg: 'ES256',
    kid: jwk.kid,
  })
  .sign(privateKey)

// Create JWE object with signed JWT as payload
const recipientJwk = {
  e: 'AQAB',
  kid: 'CZSMR6mZCn2dxWzRFP9upf2onQkVIaQld92fyb6a5HE',
  kty: 'RSA',
  n: 'uDwQ0ON7rzg6w3BobsBTf9XU6bsGAfc234beMZGHYHfFx3GZqe2YC46yd0xFKY1_yJIDzhwUMOpFfqrtHxDjER-9Q2Lwap3VLad6p3KRf-WAkEWxpgk7fkdQEkrqyxlC5GPRnwUXQ0NRlPRRgFVvlIcRQU5GG-gbPqAhM0UcdFS4He82a1YozQyByC3TG7K3gVBzeh-yT2psbpgl4UeuTnpwlRgrqxYY-PQsBHnEWJ2C7L9bZFGmUNrCOsOqe2ngJvdVit-UJKtXQ7CRx0jpR9l1d0_B0iCEi1ic6hacxYO5QMmV8tQPHHnhB2QA5zAvjXC7fIxlZoGRb1oqhZ147w',
  use: 'enc'
}
const recipientPublicKey = await importJWK(recipientJwk, 'RSA-OAEP-256')

const jwe = await new CompactEncrypt(encode(jwt))
  .setProtectedHeader({
    alg: 'RSA-OAEP-256',
    enc: 'A256GCM',
    kid: recipientJwk.kid,
  })
  .encrypt(recipientPublicKey)

Consuming a nested JWT

import { importJWK, jwtVerify, compactDecrypt } from 'jose'

const decode = TextDecoder.prototype.decode.bind(new TextDecoder());

const privateJwk = {
  e: 'AQAB',
  n: 'uDwQ0ON7rzg6w3BobsBTf9XU6bsGAfc234beMZGHYHfFx3GZqe2YC46yd0xFKY1_yJIDzhwUMOpFfqrtHxDjER-9Q2Lwap3VLad6p3KRf-WAkEWxpgk7fkdQEkrqyxlC5GPRnwUXQ0NRlPRRgFVvlIcRQU5GG-gbPqAhM0UcdFS4He82a1YozQyByC3TG7K3gVBzeh-yT2psbpgl4UeuTnpwlRgrqxYY-PQsBHnEWJ2C7L9bZFGmUNrCOsOqe2ngJvdVit-UJKtXQ7CRx0jpR9l1d0_B0iCEi1ic6hacxYO5QMmV8tQPHHnhB2QA5zAvjXC7fIxlZoGRb1oqhZ147w',
  d: 'QFgyI1Kf-wVveJzEzJF9WDNthihco8kcsBrhdXx3RJjwSYUCfxfNN5Qh_opzyVxzGbDthUnHP4JCvUejQ2tZcrycFHH0t7fiIWzR6LOZ34pfSYQd1Hh6_9KWQ51IvaBX_X5jUt-rTUGwt45Q_LpaGwzFWQKmd86r3UZ98fMcSgBIKtbZwWPd-paDC5OjOOk9fXBaAhXq19yNIQCVrCdyA9z8YD4JObTzNKxr8tdbXnQ0PqoA0VYf-ifev8uF7Q5gFDfFhARZjnssE9ZPZxMgFVF3ZE9Cg5pWjB7W-IMtnHUFtkEjHKG-ZNw2kzSDOekpJHdpBXHobq2gMTqUwFHj0Q',
  p: '8gIlcIOzQV1iJwImre5CtJ7hnhRTaNalrjeaB1BBOCGvYEjJ76GVvMVvWrXnAHhh8OYk9n-mOnRgu0BELpXA5IKDM8uEwukf2lH4mUka15vpQhdLN9qGekp-PBBIQLoQsN4yqUpRgMhYN5MKHYdM4IralAFC_1Fba44HXJYtX-c',
  q: 'wuLWQmgxtrNb9LnaBLP4O6BpwxV47i0F9Z2_PojTZEbGS-LU_YIIqmJuL0DHjZ9Yc7H06lSmCcJ2o7K_N0NZObWRRSu-kI4WwAc4z_qIlSxI0WnO2DQlBBAvcikLxZLf0lbE8bdXlc3jrypA4ADZgq-udrPQQwNPKaPHNkaaHbk',
  dp: 'KUQSbEAYxdGNlgc43zmcaD4bTKA8pMjNEYrrmcmmhVLBG9LtlA3igYDM_xO7Ywoj8TbdIKcdiiQkBmnr9mGUtaJHiwJuDepAgzKtCD499HviZ2GfctOxUJL5OXaxS1Au3mnVC6bfhO0klb1d4TEb-8HRiaE5cl3GD-309WWqMQs',
  dq: 'fz_t9t5h15G1cU4I9Rkt9IEBjcfvdlUflwixXvuoS8mKoPIzcHP_hIFQwLnjkq2A68o-yOMMp0K6hJiqEkN_dxb_C9NMUsb0Q95zUhmcJQsNYO9dh_5ETSrkT_5NGWyViJnvboTwQ3h0OmO0iI8FdzePCyLN0XPPtLij0uS2rME',
  qi: 'MP79AE4ZRtH-eVSnC6Pkzrg1qbdjCKd6mj8zZPsfNu2-8JOR_vhqN2927sH4Zou2V-m7lq0EO7xp_C9RZFhz99T6tbIXVJwR3GewGjwGc3DRuD9ih91dM1qfyApGUTN6G0jOhIaTKbBpMn1MUUZ7haBht4iypLMIfrLBNW6sLYY',
  kty: 'RSA',
  use: 'enc'
}
const privateKey = await importJWK(privateJwk, 'RSA-OAEP-256')

// decrypt the JWE
let { plaintext: decryptedJwt } = await compactDecrypt(jwe, privateKey)

const issuerPublicJwk = {
  crv: 'P-256',
  kid: 'd2bwmrR5AoI9A0FgNTFxtcNyTPlQTinRxuXUG9uOOWY',
  kty: 'EC',
  x: 'FM3c0AK77LZbxb2LCmUI-Y83DpX04HfakfD1fgfaMVw',
  y: 'fw7dMgz5uHqxbAaYUwgz0IarSIXfkGFP0qTDyC_rkx0'
}

// validate the JWT
const publicKey = await importJWK(issuerPublicJwk, 'ES256')

const { protectedHeader, payload } = await jwtVerify(decode(jwt), publicKey)
console.log(payload)

Unable to parse KeyObject for purpose of signing JWT with an EC private key.

I have been trying to read my EC private key from a file and use it to generate a signed JWT token. First I am putting my private key (a sample privateKey mentioned here) in the file my_privatekey.txt:

-----BEGIN PRIVATE KEY-----
MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCCXpUVoM4DfOtMyRVtC
eGSpVL+1tMBirnUGJHY6Y7mSHg==
-----END PRIVATE KEY-----

Following is the code to read and create a signed JWT:

const { JWT, JWS, JWK } = require('jose');
const fs = require('fs')
var crypto =require('crypto')

let keyFile = fs.readFileSync('my_privatekey.txt')
console.log("keyRaw: " + keyFile.toString());

// Using the nodejs crypto library ...
let keyObjCrypto = crypto.createPrivateKey(
  keyFile.toString(),
  'der',
  'pkcs8'
);

console.log("keyObjCrypto: " + JSON.stringify(keyObjCrypto));
console.log("asymmetricKeyType: " + keyObjCrypto.asymmetricKeyType);
console.log("type: " + keyObjCrypto.type);

// Jose code
let keyObj = JWK.asKey(keyObjCrypto, {'use': 'sig'});

let token = JWT.sign(
    {
        'claim': '<claimValue>,
    },
    keyObj,
    {
        expiresIn: '24 hours',
        header: {
            typ: 'JWT',
        },
        issuer: 'issuer,
        algorithm: 'ES256'

    })
  console.log(token);

I am getting the following error in the step JWK.asKey(keyObjCrypto, {'use': 'sig'}):

/Users/swapnil.g/node_modules/jose/lib/help/key_utils.js:92
      const { privateKey: d, publicKey: { data: publicKey } } = ECPrivateKey.decode(privateKey)
                                                ^

TypeError: Cannot read property 'data' of undefined
    at Object.private (/Users/swapnil.g/node_modules/jose/lib/help/key_utils.js:92:49)
    at module.exports.keyObjectToJWK (/Users/swapnil.g/node_modules/jose/lib/help/key_utils.js:159:56)
    at ECKey.get [as crv] (/Users/swapnil.g/node_modules/jose/lib/jwk/key/base.js:231:23)
    at new ECKey (/Users/swapnil.g/node_modules/jose/lib/jwk/key/ec.js:30:29)
    at Object.asKey (/Users/swapnil.g/node_modules/jose/lib/jwk/import.js:120:16)
    at Object.<anonymous> (/Users/swapnil.g/Desktop/walrus_signing.js:28:18)

Not sure, what else I am missing.

Also, I tried verifying the key type using openssl command on terminal. Running openssl ec -in my_privatekey.txt -noout -text outputs:

read EC key
Private-Key: (256 bit)
priv:
    00:97:a5:45:68:33:80:df:3a:d3:32:45:5b:42:78:
    64:a9:54:bf:b5:b4:c0:62:ae:75:06:24:76:3a:63:
    b9:92:1e
pub:
    04:68:d2:11:3f:69:fd:d8:80:5c:e2:c4:c4:07:0d:
    19:20:ad:f9:fc:6c:c2:7b:95:67:59:68:94:3c:5c:
    fc:0a:c1:05:1a:ec:ad:99:94:df:25:a8:6d:e6:46:
    11:62:ff:73:e8:71:b5:c5:3b:96:03:c2:72:3b:c6:
    50:00:f8:92:d0
ASN1 OID: prime256v1
NIST CURVE: P-256

on the terminal.

Can someone please help here?

bug: Unexpected character '#' on build

Describe the bug

Bundling via webpack (via netlify-lambda) fails with the following error:

ERROR in ../node_modules/@panva/jose/lib/jws/sign.js 14:2
Module parse failed: Unexpected character '#' (14:2)

(Detailed stack trace at the end of this post.)

It appears that webpack barfs at this kind of syntax with the #

class Sign {
  #b64
  #payload
  #recipients
  ...

I'm submitting an issue here because '#' appears to be invalid syntax.

To Reproduce

Steps to reproduce the behaviour:

  1. git clone https://github.com/rendall/jwt-implementation/tree/%40panva/jose
  2. cd ./jwt* or otherwise into project directory
  3. npm / yarn install
  4. npm / yarn run build

Expected behaviour

That there be no Unexpected character error.

Environment:

  • @panva/jose version: 1.0.0
  • node version: v12.0.0

Additional context
Add any other context about the problem here.

  • the bug is happening on latest @panva/jose too.
  • i have tried DEBUG (see readme.md) and can see the issue is with the provider and not my code.
  • i have searched the issues tracker on github for similar issues and couldn't find anything related.

Detailed Error stack trace

netlify-lambda: Building functions
Hash: c3ac99528bc9843d63e5
Version: webpack 4.30.0
Time: 2110ms
Built at: 04/27/2019 7:55:37 AM
  Asset     Size  Chunks  Chunk Names
auth.js  124 KiB       0  auth
Entrypoint auth = auth.js
 [0] external "crypto" 42 bytes {0} [built]
 [2] ../node_modules/@panva/jose/lib/errors.js 275 bytes {0} [built] [failed] [1 error]
 [5] ../node_modules/@panva/jose/lib/jwk/key/base.js 5.89 KiB {0} [built]
[10] ../node_modules/@panva/jose/lib/jwks/keystore.js 202 bytes {0} [built] [failed] [1 error]
[16] ../node_modules/@panva/jose/lib/jwk/generate.js 1.5 KiB {0} [built]
[18] ../node_modules/@panva/jose/lib/jws/index.js 525 bytes {0} [built]
[31] ../node_modules/@panva/jose/lib/jwk/index.js 298 bytes {0} [built]
[37] ../node_modules/@panva/jose/lib/index.js 178 bytes {0} [built]
[38] ../node_modules/dotenv/lib/main.js 2.87 KiB {0} [built]
[39] ./auth.js 3.21 KiB {0} [built]
[40] ../node_modules/@panva/jose/lib/jwe/index.js 570 bytes {0} [built]
[85] ../node_modules/@panva/jose/lib/jwks/index.js 70 bytes {0} [built]
[89] ../node_modules/@panva/jose/lib/jwt/index.js 150 bytes {0} [built]
[92] external "fs" 42 bytes {0} [built]
[93] external "path" 42 bytes {0} [built]
    + 79 hidden modules

ERROR in ../node_modules/@panva/jose/lib/jws/sign.js 14:2
Module parse failed: Unexpected character '#' (14:2)
You may need an appropriate loader to handle this file type.
|
| class Sign {
>   #b64
|   #payload
|   #recipients
 @ ../node_modules/@panva/jose/lib/jws/index.js 1:13-30
 @ ../node_modules/@panva/jose/lib/index.js
 @ ./auth.js

Error [ERR_PACKAGE_PATH_NOT_EXPORTED]

I keep on getting this error since I installed this module yesterday

 Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: No "exports" main defined in /home/dev/projects/api/node_modules/jose/package.json
at throwExportsNotFound (internal/modules/esm/resolve.js:290:9)
at packageExportsResolve (internal/modules/esm/resolve.js:513:3)
at resolveExports (internal/modules/cjs/loader.js:432:36)
at Function.Module._findPath (internal/modules/cjs/loader.js:472:31)
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:867:27)
at Module.Hook._require.Module.require (/usr/lib/node_modules/pm2/node_modules/require-in-the-middle/index.js:61:29)
at require (internal/modules/cjs/helpers.js:88:18)
at Object.<anonymous> (/home/dev/projects/api/src/utils/utils.ts:5:14)
at Module._compile (internal/modules/cjs/loader.js:1063:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10) {
code: 'ERR_PACKAGE_PATH_NOT_EXPORTED'
}

Environment:

  • jose version: [e.g. v3.5.1]
  • affected runtime is: [e.g. Node.js 14.15.4 npm version 6.14.11

My tscongig:

{
  "compilerOptions": {
    "module": "commonjs",
    "esModuleInterop": true,
    "resolveJsonModule": true,
    "target": "es6",
    "noImplicitAny": false,
    "moduleResolution": "node",
    "sourceMap": true,
    "outDir": "dist",
    "baseUrl": ".",
    "paths": {
      "*": [
        "node_modules/*",
        "src/types/*"
      ]
    },
    "lib": [
      "es2015"
    ]
  },
  "include": [
    "src/**/*"
  ]
}

Possibly related dependencies I use:

{"typescript": "^4.1.3",
    "webpack": "^5.12.3",
    "webpack-cli": "^4.3.1",
    "webpack-dev-server": "^3.11.1"
  },

bug: Generating EC-512 keys

Describe the bug
When generating EC-512 keys intuitively you would want to use JWK.generate('EC','P-512'). However if you look at the evaluation of the second parameter (crvToDSA) in the file /lib/jwk/key/ec.js (line 29) you have to use P-521. Not sure if it's a typo or a bug.

To Reproduce
Try running JWK.generate('EC','P-512'). It will give this exception: JOSENotSupported: unsupported EC key curve: P-512

Environment:

  • @panva/jose version: v1.2.0

  • node version: v12.4.0

  • the bug is happening on latest @panva/jose too.

  • i have searched the issues tracker on github for similar issues and couldn't find anything related.

importing modules inside of ESM package fails

Describe the bug

Importing a module from this package inside of an ESM enabled package results in an Error.

To Reproduce

I have a gist here: https://gist.github.com/ksmithut/d5f787fa0eca67295c5d360054fccf82

  • macOS 11.0.1
  • node 15.2.0

You can clone it and run it:

git clone https://gist.github.com/ksmithut/d5f787fa0eca67295c5d360054fccf82 reproduce
cd reproduce
npm install
npm start

Code to reproduce the behaviour:

{
  "type": "module",
  "dependencies": {
    "jose": "^3.0.1"
  }
}
import generateKeyPair from 'jose/util/generate_key_pair'

Expected behaviour

To import the module in an ESM environment.

Environment:

  • jose version: v3.0.1
  • affected runtime is: Node.js 15.2.0 and Node.js 14.15.0 tested

Additional context

Perhaps if the ESM module files were exported with a .mjs extension it would work as expected? I'm not sure what the right answer is for modules exporting both CJS and ESM.

  • the bug is happening on latest jose too.
  • i have searched the issues tracker on github for similar issues and couldn't find anything related.

bug: Mixed stores may generate JWKS with duplicate keys

Describe the bug

If a store contains private keys and it's public key then toJWKS() would generate JWKS with two equal public keys

To Reproduce

const jose = require('@panva/jose')

const privateKey = `-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp
wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5
1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh
3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2
pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il
AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF
L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k
X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
-----END RSA PRIVATE KEY-----`

const publicKey = `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0
FPqri0cb2JZfXJ/DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/
3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQAB
-----END PUBLIC KEY-----`
  
const publicJWK = jose.JWK.asKey(publicKey)
const privateJWK = jose.JWK.asKey(privateKey)
const store = new jose.JWKS.KeyStore()
store.add(publicJWK)
store.add(privateJWK)
console.log(store.toJWKS())

Expected behaviour

{
  keys: [
    {
      e: 'AQAB',
      kid: '7NQlxI5TqY9CtGYwf5yw8p3XXpT7SJNMol2xvbyUtGU',
      kty: 'RSA',
      n: 'qhirpDtQ3u84WY-vh9KrY05FccEwqbynuHgmdBT6q4tHG9iWX1yfw4GEher1KcJiRvMFUGSo3hnIwzi-VJbLrrBZ3As1gUO0SjVEnrJkETEhpFW9f94_rJGelLVvubtPZRzbI-rUOdbNUj6wgZHnWzX9E6dBmzCQ8keHvU9OGWc'
    },
    {
      e: 'AQAB',
      kid: '7NQlxI5TqY9CtGYwf5yw8p3XXpT7SJNMol2xvbyUtGU',
      kty: 'RSA',
      n: 'qhirpDtQ3u84WY-vh9KrY05FccEwqbynuHgmdBT6q4tHG9iWX1yfw4GEher1KcJiRvMFUGSo3hnIwzi-VJbLrrBZ3As1gUO0SjVEnrJkETEhpFW9f94_rJGelLVvubtPZRzbI-rUOdbNUj6wgZHnWzX9E6dBmzCQ8keHvU9OGWc'
    }
  ]
}

Environment:

  • @panva/jose version: [e.g. v1.9.2]
  • node version: [e.g. v12.0.0]

Additional context
Add any other context about the problem here.

If two equal public keys would be added to a store then .toJWKS() would not include duplicates. I think in this case .toJWKS() should not generate duplicates as well

  • the bug is happening on latest @panva/jose too.
  • i have searched the issues tracker on github for similar issues and couldn't find anything related.

Yarn 2 (PnP) Problems

I'm unable to import jose in a project managed with yarn 2.

Ex:

mkdir /tmp/bad; cd /tmp/bad
yarn set version berry
yarn init
yarn add jose
echo "import { jwtVerify } from 'jose/jwt/verify';" > test.mjs
yarn node test.mjs

This results in

internal/process/esm_loader.js:74
    internalBinding('errors').triggerUncaughtException(
                              ^

Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'jose' imported from /tmp/bad/test.mjs
    at packageResolve (internal/modules/esm/resolve.js:655:9)
    at moduleResolve (internal/modules/esm/resolve.js:696:18)
    at Loader.defaultResolve [as _resolve] (internal/modules/esm/resolve.js:810:11)
    at Loader.resolve (internal/modules/esm/loader.js:85:40)
    at Loader.getModuleJob (internal/modules/esm/loader.js:229:28)
    at ModuleWrap.<anonymous> (internal/modules/esm/module_job.js:51:40)
    at link (internal/modules/esm/module_job.js:50:36) {
  code: 'ERR_MODULE_NOT_FOUND'
}

Using classic yarn, there is no problem

mkdir /tmp/good; cd /tmp/good
yarn init
yarn add jose
echo "import { jwtVerify } from 'jose/jwt/verify';" > test.mjs
yarn node test.mjs

This gives:

yarn node v1.22.10
Done in 0.11s.

Any suggestions?

Error: Cannot find module 'jose'

I tried use it for azure functions. It's not seems working.

I installed npm install --save-dev @types/node but still getting the issue.

Node version: v10.15.3

JWK generate does not recognize options object

Describe the bug

when running

JWK.generateSync("RSA", 2048, {use: 'enc'})

it produces error

TypeError: parameters argument must be a plain object when provided
    at asKey (/home/runner/JOSE/node_modules/jose/lib/jwk/import.js:39:11)
    at Object.generateSync (/home/runner/JOSE/node_modules/jose/lib/jwk/generate.js:40:14)
    at /home/runner/JOSE/index.js:11:5
    at Script.runInContext (vm.js:131:20)
    at Object.<anonymous> (/run_dir/interp.js:156:20)
    at Module._compile (internal/modules/cjs/loader.js:1133:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1153:10)
    at Module.load (internal/modules/cjs/loader.js:977:32)
    at Function.Module._load (internal/modules/cjs/loader.js:877:14)

To Reproduce

Steps to reproduce the behaviour:

  1. Use JWK.generate/generateSync with options

Expected behaviour
A clear and concise description of what you expected to happen.

should not produce error

Environment:

  • jose version: [e.g. v1.0.0]

1.27.1

  • node version: [e.g. v12.0.0]

v12.16

Additional context
Add any other context about the problem here.

  • the bug is happening on latest jose too.
  • i have searched the issues tracker on github for similar issues and couldn't find anything related.

i do not seem to be getting this issue on v12.18.0

the code which produced the error was run on repl.it

ECONNREFUSED when using createRemoteJWKSet

When using createRemoteJWKSet this error is being generated:
Error: connect ECONNREFUSED 127.0.0.1:443\n at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16)

I tried with different urls like so:
const AppleJWKS = createRemoteJWKSet(new URL("https://appleid.apple.com/auth/keys"));
or the example one:
const JWKS = createRemoteJWKSet(new URL('https://www.googleapis.com/oauth2/v3/certs'))
with the same error as output.

When debugging the error I noticed that in the fetch.js file the https library is being used and the on('error' listener being triggered.

When changing:
protocols[url.protocol](url, { agent, timeout }, async (response) => {
for
protocols[url.protocol](url.href, async (response) => {
the code proceeds properly.

I don't really get what is causing the error but if I use a URL object in the https module it doesn't work.

Code to reproduce the behaviour:

// formatted code snippet that reproduces the behaviour
const AppleJWKS = createRemoteJWKSet(new URL("https://appleid.apple.com/auth/keys"));
let tokenPayload = await jwtVerify(req.body.token, AppleJWKS, {
  audience: config.APPLE_APP_ID
});

Expected behaviour
It should make the https call properly and parse the JWKS so it can be used for JWT validation.

Environment:

  • jose version: 3.5.2

  • affected runtime is: Node.js v12.18.2

  • [ x] the bug is happening on latest jose too.

  • [ x] i have searched the issues tracker on github for similar issues and couldn't find anything related.

Module not found - Node version 14.15.1

Hello

I want to use your library, especially jwt part of your library. But, when I import jose/jwr/sign with ESM import, I have an error on module not found :

Module not found: Error: Can't resolve 'jose/jwt/sign'

To Reproduce

I initialized an angular project and I ran npm install jose@3

Code to reproduce the behaviour:

import { Component } from '@angular/core';
import SignJWT from 'jose/jwt/sign'


@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'metabase';

  constructor() {
    this.test();
  }

  public async test() {
    const secretKey = ''';

    var string = btoa(unescape(encodeURIComponent(secretKey))),
      charList = string.split(''),
      uintArray = [];
    for (var i = 0; i < charList.length; i++) {
      uintArray.push(charList[i].charCodeAt(0));
    }
    var key = new Uint8Array(uintArray);
    const jwt = await new SignJWT({ 'urn:example:claim': true })
      .setProtectedHeader({ alg: 'ES256' })
      .setIssuedAt()
      .setIssuer('urn:example:issuer')
      .setAudience('urn:example:audience')
      .setExpirationTime('2h')
      .sign(key)

  }

}

Environment:

  • jose version: v3.5.1
  • affected runtime is: Node.js 14.15.1]

What I did wrong ?

question: How do I get the thumbprint of a key

Hi,

I'm kind of new to the world of JW*, and I need to get the thumbprint of a key, how do I do that using this library ?

(I already imported the key from a file. I need to create a JWE and, according to the document i got, I have to add the key's thumbprint to the protected headers)

Best regards,

V3: Typescript missing type declarations

When installing newest version (3.0.1) there seems that typescript declarations is missing.
Get error:
Cannot find module 'jose' or its corresponding type declarations.ts(2307)

Reproduce;
npm install [email protected]
Create typescript file:
import { JWK, JWKS } from 'jose';
Typescript linter will complain of missing type declarations.

This worked on V 2.0.3.

bug: keystore.toJWKS throws on windows

I'm trying to generate a key, i used the code i found in the doc

const { JWKS: { KeyStore } } = require('@panva/jose');
const keystore = new KeyStore();
keystore.generateSync('RSA', 2048, {
  alg: 'RS256',
  use: 'sig',
});
console.log('this is the full private JWKS:\n', keystore.toJWKS(true));

But when i try to start it i get this error

E:\HAS\OpenId\node_modules\@trust\keyto\src\index.js:231
        throw new InvalidOperationError('key is not a valid PEM string')
        ^

Error: key is not a valid PEM string
    at Function.from (E:\HAS\OpenId\node_modules\@trust\keyto\src\index.js:231:15)
    at module.exports.keyObjectToJWK (E:\HAS\OpenId\node_modules\@panva\jose\lib\help\key_utils.js:13:16)
    at RSAKey.get [as e] (E:\HAS\OpenId\node_modules\@panva\jose\lib\jwk\key\base.js:84:23)
    at RSAKey.[THUMBPRINT_MATERIAL] (E:\HAS\OpenId\node_modules\@panva\jose\lib\jwk\key\rsa.js:78:22)
    at RSAKey.get [as kid] (E:\HAS\OpenId\node_modules\@panva\jose\lib\jwk\key\base.js:39:97)
    at Function.entries (<anonymous>)
    at RSAKey.toJWK (E:\HAS2\OpenId\node_modules\@panva\jose\lib\jwk\key\base.js:60:27)
    at keys.map.key (E:\HAS2\OpenId\node_modules\@panva\jose\lib\jwks\keystore.js:95:60)
    at Array.map (<anonymous>)
    at KeyStore.toJWKS (E:\HAS\OpenId\node_modules\@panva\jose\lib\jwks\keystore.js:95:45)

If i understand correctly this is suppose to directly generate a key? I don't see in the doc the need for another file so maybe i'm not understanding something and i know you are probably very busy atm but if there are things i can do to help let me know :x

bug: cannot retrieve key from JWKS when alg = RSA-OAEP-256

Describe the bug

The following leads to an undefined return value, but I would expect the key to be returned

const { JWKS } = require('jose');
const keystore = new JWKS.KeyStore();

async function test(){
	await keystore.generate('RSA', 2048, {
			use: 'enc',
			alg: 'RSA-OAEP-256',
			kid: 'gHKpbutlpxI6PrJKHwWWUYnP1XY5uZv4hoNadnwki8X',
		});
// returns undefined but would expect the key to be logged
console.log(keystore.get({alg: 'RSA-OAEP-256', use: 'enc'});
}

test();

Expected behaviour
I would expect a key to be returned in this case instead of undefined.

Environment:

  • jose version: v1.10.1 (and also on 1.9.2 of @panva/jose)

  • node version: v10.16.3

  • the bug is happening on latest jose too.

  • i have searched the issues tracker on github for similar issues and couldn't find anything related.

bug: Generate OKPKeys: TypeError [ERR_INVALID_ARG_TYPE]

Describe the bug
When I want to create OKP Keys I get an error:

TypeError [ERR_INVALID_ARG_TYPE]: The "options" argument must be of type object. Received type undefined
    at check (internal/crypto/keygen.js:163:11)
    at generateKeyPair (internal/crypto/keygen.js:33:16)
    at Promise (internal/util.js:274:30)
    at new Promise (<anonymous>)
    at generateKeyPair (internal/util.js:273:12)

To Reproduce

Code to reproduce:

const fs = require('fs')
const path = require('path')
const jose = require('jose')

const keystore = new jose.JWKS.KeyStore()

Promise.all([
  // ...
  keystore.generate('OKP', 'Ed25519', { use: 'sig' })
]).then(() => {
  fs.writeFileSync(path.resolve(__dirname, './keystore.json'), JSON.stringify(keystore.toJWKS(true), null, 2))
})
.then(() => console.log('Generate complete.'))
.catch(console.error)

Expected behaviour
No error

Environment:

  • jose version: latest
  • node version: latest

Additional context
Add any other context about the problem here.

  • the bug is happening on latest jose too.
  • i have searched the issues tracker on github for similar issues and couldn't find anything related.

bug: Can't sign or encrypt on Node v11.14.0

Describe the bug
This package does not work properly on Node v11.14.0. Using the JWT.sign() and/or JWE.encrypt() method(s) result in the following exception:

TypeError: keyObject.asInput is not a function
    at sign (/node_modules/@panva/jose/lib/jwa/rsassa_pss.js:25:27)
    at sign (/node_modules/@panva/jose/lib/jwa/index.js:58:29)
    at Sign.[PROCESS_RECIPIENT] (/node_modules/@panva/jose/lib/jws/sign.js:108:50)
    at Array.forEach (<anonymous>)
    at Sign.sign (/node_modules/@panva/jose/lib/jws/sign.js:126:24)
    at single (/node_modules/@panva/jose/lib/jws/index.js:7:14)
    at Object.module.exports [as sign] (/node_modules/@panva/jose/lib/jwt/sign.js:77:14)
    at Object.<anonymous> (/dist/modules/authorize/index.js:12:24)
    at Module._compile (internal/modules/cjs/loader.js:816:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:827:10)
    at Module.load (internal/modules/cjs/loader.js:685:32)
    at Function.Module._load (internal/modules/cjs/loader.js:620:12)
    at Module.require (internal/modules/cjs/loader.js:723:19)
    at require (internal/modules/cjs/helpers.js:14:16)
    at Object.<anonymous> (/dist/server.js:8:21)
    at Module._compile (internal/modules/cjs/loader.js:816:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:827:10)
    at Module.load (internal/modules/cjs/loader.js:685:32)
    at Function.Module._load (internal/modules/cjs/loader.js:620:12)
    at Function.Module.runMain (internal/modules/cjs/loader.js:877:12)
    at internal/main/run_main_module.js:21:11

To Reproduce

Steps to reproduce the behaviour:

const jose = require('@panva/jose');

const jwk = jose.JWK.generate("RSA");
const jwt = jose.JWT.sign({ abc: 123 }, jwk);
const jwe = jose.JWE.encrypt(jwt, jwk);

Expected behaviour
Proper signing and encryption of the token.

Environment:

  • @panva/jose version: 1.9.1
  • node version: v11.14.0

Additional context
The README file states that Node >= v12.0.0 is recommended, so this might be a wontfix. BUT the information in this issue might be useful to others.

  • the bug is happening on latest @panva/jose too.
  • i have searched the issues tracker on github for similar issues and couldn't find anything related.

bug: detached jws encoding error

Describe the bug
The way utf-8 encoding is applied to detached jws causes incompatibility issues.

To Reproduce

transmute-industries/json-ld-sig-detached-jws#1

Steps to reproduce the behaviour:

  1. Try to sign with b64: false some arbitrary binary
  2. observe the jws that is produced does not match expectations for b64 false
  3. base64url decode assumes utf8 encoded characters

Expected behaviour
base64url decode applied to the payload should not assume utf8.

Environment:
"@panva/jose": "^1.9.3",
"jose": "^1.16.0",

  • node version: v12.0.0

Additional context

  • [X ] i have searched the issues tracker on github for similar issues and couldn't find anything related.

bug: invalid token

You updated 'jose' package yesterday in github but still changes not received on npm install of 'JOSE' package. So in key_object.js file showing error as unexpected token for 0n.

Payload gets mangled by JWS signing with multiple recipients + unencoded payload

Describe the bug

Using unencoded option (RFC7797) with multiple signatures/recipients causes the payload to the signed JWS to get garbled.

To Reproduce

Following code will reproduce the issue:

jose = require('jose')

var key1 = jose.JWK.generateSync('EC')
var key2 = jose.JWK.generateSync('EC')

var payload = 'test'
var signer = new jose.JWS.Sign(payload)
signer.recipient(key1, { b64: false, crit: ['b64'] }, {})
signer.recipient(key2, { b64: false, crit: ['b64'] }, {})
signer.sign('general')

The result is:

{
  payload: '๏ฟฝ๏ฟฝ-',
  signatures: [
    {
      protected: 'eyJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdLCJhbGciOiJFUzI1NiJ9',
      header: {},
      signature: 'O63LN2RxA2aa3QoCAR2PmfJDciDGrzlJYOWF-d1JDiczHHWG_VdMZvNfof6QWvK3H3q-0LsfuCacdZng6ELLPA'
    },
    {
      protected: 'eyJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdLCJhbGciOiJFUzI1NiJ9',
      header: {},
      signature: 'fKWZYFlY0HWRrF1mb3TacaLMK_awINlVWriZkwK6Re7HxtznJu6jOL99mE4oA11U8w1k3p8-L9iUBsGZiRuxrA'
    }
  ]
}

Note: the weird characters in the payload. Should just be test.

Expected behaviour

The result should look like this:

{
  payload: 'test',
  signatures: [
    {
      protected: 'eyJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdLCJhbGciOiJFUzI1NiJ9',
      header: {},
      signature: 'O63LN2RxA2aa3QoCAR2PmfJDciDGrzlJYOWF-d1JDiczHHWG_VdMZvNfof6QWvK3H3q-0LsfuCacdZng6ELLPA'
    },
    {
      protected: 'eyJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdLCJhbGciOiJFUzI1NiJ9',
      header: {},
      signature: 'fKWZYFlY0HWRrF1mb3TacaLMK_awINlVWriZkwK6Re7HxtznJu6jOL99mE4oA11U8w1k3p8-L9iUBsGZiRuxrA'
    }
  ]
}

Environment:

  • jose version: [e.g. v1.27.2]
  • node version: [e.g. v14.5.0]

Additional context
Add any other context about the problem here.

The above code works as expected if only one recipient is added before signing.

  • [X ] the bug is happening on latest jose too.
  • i have searched the issues tracker on github for similar issues and couldn't find anything related.

Compile fail CryptoKey

I don't know if the problem was a bug or me doing something wrong.
When I try to build my package, something go wrong.

yarn run v1.22.5
$ rm -rf ./dist/* && mkdir -p ./dist && tsc
node_modules/jose/dist/types/types.d.ts:92:35 - error TS2304: Cannot find name 'CryptoKey'.

92 export type KeyLike = KeyObject | CryptoKey | Uint8Array
                                     ~~~~~~~~~


Found 1 error.

error Command failed with exit code 2.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
The terminal process "/bin/bash '-c', 'yarn run build'" terminated with exit code: 2.

Node 14, same error on docker.

bug: Invalid or unexpected token at Module._compile

When i was running the test for the node-oidc i got this

\node-oidc-provider\node_modules@panva\jose\lib\jwe\encrypt.js:21
#aad
^

SyntaxError: Invalid or unexpected token
at Module._compile (internal/modules/cjs/loader.js:743:23)

I suppose on the encrypt.js it should be // instead of # ?

Algorithm Selection Guide

See also Algorithm Key Requirements.

How to select a JOSE / JWT cryptographic algorithm for your application

The need to secure tokens comes from a number concerns, any of which may apply to your particular use case:

  • Integrity: Verify that the token has not been tampered with
  • Authenticity: The origin of the token can be verified
  • Non-repudiation: The authenticity and integrity of the token is verifiable by third parties
  • Confidentiality: Token payload is kept secret from unauthorized parties

Understanding which security objectives we're after is the first step in selecting an appropriate JOSE algorithm.

This guide is in large inspired by c2id nimbus-jose-jwt which its authors have graciously allowed me to gather copies and content from.

Available JOSE algorithm classes

Integrity Authenticity Non-repudiation Confidentiality
HMAC โœ” โœ”
Digital signatures โœ” โœ” โœ”
Public-key encryption โœ” โœ”
Authenticated encryption โœ” โœ” โœ”
Nested signing and encryption โœ” โœ” โœ” โœ”

HMAC algorithms: An efficient hash (HMAC) for ensuring the integrity and authenticity of data. In order to compute an HMAC you need a secret key.

Digital signatures: Offers the properties of HMAC, plus cryptographic non-repudiation (enabling others than the signer to check the signature's validity). Digital signatures are based on public / private key cryptography. Requires a public / private key pair (of type RSA, elliptic curve (EC), or Edwards-curve Octet Key Pair (OKP)).

Public-key encryption: Encrypt data using the recipient's public key. Note that the receiver cannot verify the origin of encrypted messages - unless combined with a digital signature. Requires a public / private key pair (of type RSA, elliptic curve (EC), or Edwards-curve Octet Key Pair (OKP))

Authenticated encryption: Encrypt data, while also ensuring its integrity and authenticity (like HMAC). Authenticated encryption requires that a shared secret must be exchanged via a secure channel beforehand. JOSE offers encryption with secret (shared) keys and with passwords.

Nested signing and encryption: Combine a digital signature with public-key encryption to achive all security objectives (integrity, authenticity, non-repudiation and confidentiality). Note, that non-repudiation may not always be a design goal (because this proves the origin of a message to third parties).

HMAC

Key type: Symmetric Secret keys (oct)
Algorithms: HS256, HS384, HS512

Use when you're both the issuer and recipient of the token. E.g. when you want to sign your cookie values.

Notes:

  • The HMAC is not a digital signature.
  • Secrets shorter than the hash size are forbidden by the specification.
  • Secrets longer than the hash size don't provide additional security.
  • Payloads protected by HMAC are NOT encrypted, they're just encoded to be URL safe.

Digital Signatures

Key type: Public / Private key pairs (RSA, EC, OKP)
Algorithms:

  • RSA signature with PKCS #1 and SHA-2: RS256, RS384, RS512
  • RSA PSS signature with SHA-2: PS256, PS384, PS512
  • ECDSA signature with SHA-2: ES256, ES256K, ES384, ES512
  • Edwards-curve DSA: EdDSA

Use when producing tokens, statements, assertions and documents which integrity and authenticity must be verifiable by third parties. E.g. access tokens, identity tokens, proofs of key possession.

Notes:

  • The signature is computed with a private key, which must be kept private at all times.
  • The signature of a JWT or JWS is validated with the public key, which is free to be distributed to the token's recipients.
  • Payloads protected by Digital signatures are NOT encrypted, they're just encoded to be URL safe.
  • RSA keys of less than 2048 bits are forbidden by the specification.
  • Algorithms have varying sign/verify throughput, RSA-based depend on the chosen key size, ECDSA and EdDSA depend on the key's curve.

Public-Key Encryption

Key type: Public / Private key pairs (RSA, EC, OKP)
Algorithms:

  • RSA key pair encryption algorithms: RSA-OAEP, RSA-OAEP-256, RSA-OAEP-384, RSA-OAEP-512
  • EC key pair encryption algorithms using ECDH: ECDH-ES, ECDH-ES+A128KW, ECDH-ES+A192KW, ECDH-ES+A256KW
  • OKP key pair encryption algorithms using ECDH: ECDH-ES, ECDH-ES+A128KW, ECDH-ES+A192KW, ECDH-ES+A256KW

Encrypt using the recipient's public key when you want the token payloads to remain confidential. Recipients will decrypt using their private key. Note that the receiver cannot verify the origin of encrypted messages - unless combined with a digital signature.

Notes:

  • Public-key encryption is also known as asymmetric encryption.
  • Encrypting an HMAC JWS/JWT is redundant, use authenticated encryption with a symmetric secret instead.
  • Do not use Public/Private key pair schemes when you're both the issuer and recipient, better use direct symmetric encryption in such case.
  • JWE payload can be anything, e.g. a serialized JWT Claims Set or a even a complete JWT. When the payload is a complete JWT this is called a Nested JWT.
  • The payload encryption ("enc") is always AES based using a random content encryption key which is managed using the algorithms ("alg") described above.
  • RSA keys of less than 2048 bits are forbidden by the specification.

Authenticated Encryption

Key type: Symmetric Secret keys (oct) or Passwords
Algorithms:

  • Direct Encryption using a shared secret: dir
  • AES key wrap using a shared secret: A128KW, A192KW, A256KW
  • AES GCM key encryption using a shared secret: A128GCMKW, A192GCMKW, A256GCMKW
  • Password based encryption: PBES2-HS256+A128KW, PBES2-HS384+A192KW, PBES2-HS512+A256KW

Encrypt using a symmetric secret in case you encrypt data for yourself or in case a shared secret has been exchanged beforehand via a secure channel. Use a password based scheme when encrypting data with a rememberable passphrase.

Notes:

  • With the exception of "dir" all JWEs encrypt their payloads with a random content encryption key which is managed using the algorithms ("alg") described above. The payload encryption ("enc") is always AES based (either in CBC or GCM mode, when CBC is used SHA-2 is used to compute an authentication tag).
  • JWE payload can be anything, e.g. a serialized JWT Claims Set or a even a complete JWT. When the payload is a complete JWT this is called a Nested JWT.
  • Symmetric encryption in JOSE is always authenticated.

Nested signing and encryption

A signed JWT / JWS object can be additionally encrypted, thus providing integrity, authenticity, non-repudiation and confidentiality to data.

This is achieved by nesting (see #112).
To produce: The JWT is signed with a private RSA, EC or OKP key. The signed JWT then becomes the payload (plaintext) of a JWE object, which is encrypted with either the public key (RSA, EC, OKP) of the recipient, or with a secret key that has been shared between the two parties.
To consume: The JWE object is decrypted with the appropriate key (private key for RSA, EC or OKP, or established secret key). The extracted payload (plaintext) is then parsed as a signed JWT, and verified with the issuer's public key (RSA, EC or OKP).

bug: getCurves is not a function

Describe the bug
I get TypeError: getCurves is not a function

To Reproduce

Steps to reproduce the behaviour:

  1. Install Jose
  2. Import:

import {JWT} from "jose";

  1. npm run start
**Expected behaviour**
Not crash

**Environment:**
 - `jose` version: 1.24.0
 - node version: 13.9.0

**Additional context**
Add any other context about the problem here.

 - [x ] the bug is happening on latest `jose` too.
 - [x ] i have searched the issues tracker on github for similar issues and couldn't find anything related. 
The nearest I found is:
[]( https://stackoverflow.com/questions/59871686/crypto-getcurves-is-undefined)

#aad is not a bug.

Node >=12.0.0 is the described minimal version of @panva/jose. It is for its crypto standard module additions such as KeyObject and one-shot sign/verify APIs that are only available in the Node 12 track.

This weird looking syntax is actually private class field and it is just something which I'm glad to have available as a side effect of needing Node 12 for its APIs.

Should the needed APIs land on the Node 10 release line I will remove this syntax and release a Node 10 compatible version. It is just not very likely seeing how far behind the feature backports to Node 10 are.

Cannot seem to import jwtVerify from a TypeScript file and run jest tests against it

Describe the bug

When importing jwtVerify from a .ts file and trying to leverage exported function from jest .ts tests, we're getting import related errors

$ jest
FAIL src/__tests__/a.ts
  โ— Test suite failed to run

    Cannot find module 'jose/jwt/verify' from 'src/a.ts'

    Require stack:
      src/a.ts
      src/__tests__/a.ts

    > 1 | import jwtVerify, { JWTVerifyGetKey } from 'jose/jwt/verify';
        | ^
      2 | 
      3 | const keyRetriever: JWTVerifyGetKey = (_header, _token) => {
      4 |   return Promise.resolve(new Uint8Array(2));

      at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:306:11)
      at Object.<anonymous> (src/a.ts:1:1)

To Reproduce

A complete end to end repro case is available at https://github.com/nulltoken/jose-import-repro-case

clone, then run yarn.

  • building works fine (ie. yarn build doesn't report any error)
  • running tests fails with the above error

In order to help studying the repro case, a GitHub action has been created => https://github.com/nulltoken/jose-import-repro-case/blob/main/.github/workflows/main.yml
Results of latest run can be audited at https://github.com/nulltoken/jose-import-repro-case/runs/1702720189?check_suite_focus=true

Expected behaviour

Full disclosure: I may not be properly importing the lib (the README doesn't explicitly describe the recommended way to import from TypeScript)

If jose 3.5.1 is supposed to work in the described usage, an update in the README would be great.
If this is a bug, well... I'd really enjoy being able to use this lib and run jest based TypeScript tests against functions leveraging it.

Environment:

  • jose version: 3.5.1
  • affected runtime is: Node.js 14.15.0,
  • other relevant library versions: available in the package.json in the linked repro repository

Additional context
Add any other context about the problem here.

  • the bug is happening on latest jose too.
  • i have searched the issues tracker on github for similar issues and couldn't find anything related.

Build issues on Ubuntu 20.04.1 LTS

I ran npm run build-all and it did not work.

Had some issues with the find commands when running them on my system, if maxdepth is used in find it likes to be the first named argument for some reason. I also had to play with the sed inline replace to get it to work.

Code to reproduce the behaviour:

npm run build-all

Expected behaviour
Build scripts should work on debian (ubuntu) systems.

Environment:

  • jose version: latest
  • affected runtime is: Node.js v10.19.0, Ubuntu 20.04.1 LTS

Additional context
Here is the diff I applied to the package.json to get this working for my environment:

- "runtime:find": "find src/runtime -not -name '*.d.ts' -maxdepth 1 -type f -print0",
+ "runtime:find": "find src/runtime -maxdepth 1 -type f -not -name \"*.d.ts\" -print0",
- "runtime:refs": "run-s -s runtime:find | xargs -0 sed -i '' -e \"s/'\\.\\.\\//'\\.\\//g\" -e \"s/'\\.\\/\\.\\./'../g\"",
+ "runtime:refs": "find src/runtime/ -maxdepth 1 -type f -not -name \"*.d.ts\" -exec sed -i -e \"s/'\\.\\.\\//'\\.\\//g\" -e \"s/'\\.\\/\\.\\./'../g\" '{}' ';'",

Perhaps its worth mentioning something in the docs (troubleshooting etc) if you agree?

bug: jti not used during JWT.sign

When using JWT.sign, jti can be supplied as an option for it to be included in the payload.
However, jti is currently not included in the payload generation
see below:

jose/lib/jwt/sign.js

Lines 65 to 74 in 10a1b64

payload = {
...payload,
sub: subject || payload.sub,
aud: audience || payload.aud,
iss: issuer || payload.iss,
iat: iat ? unix : payload.iat,
nonce: nonce || payload.nonce,
exp: expiresIn ? unix + secs(expiresIn) : payload.exp,
nbf: notBefore ? unix + secs(notBefore) : payload.nbf
}

Additional context
Add any other context about the problem here.

  • the bug is happening on latest @panva/jose too.
  • i have searched the issues tracker on github for similar issues and couldn't find anything related.

bug: #keys??

Describe the bug
I got this when doing webpack bundle targeting "node".

ERROR in ./node_modules/@panva/jose/lib/jwks/keystore.js 40:2
Module parse failed: Unexpected character '#' (40:2)
You may need an appropriate loader to handle this file type.
|
| class KeyStore {
>   #keys
|
|   constructor (...keys) {
 @ ./node_modules/@panva/jose/lib/jwks/index.js 1:17-38

#keys should be not a valid variable name. Is it intended?

To Reproduce

Steps to reproduce the behaviour:

Expected behaviour
A clear and concise description of what you expected to happen.

Environment:

  • @panva/jose version: [e.g. v1.0.0]
  • node version: [e.g. v12.0.0]

Additional context
Add any other context about the problem here.

  • the bug is happening on latest @panva/jose too.
  • i have tried DEBUG (see readme.md) and can see the issue is with the provider and not my code.
  • i have searched the issues tracker on github for similar issues and couldn't find anything related.

suggestion: replace asn1.js with any updated fork

Describe the bug
Using jose will sometimes throw DeprecationWarning due to the fact that the dependency asn1.js is outdated and seems abandoned (the fix PR is open since march/2018).

Message

(node:29508) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.

Environment:

  • jose version: 1.18.1
  • node version: v12.13.0

Some reading material
indutny/asn1.js#116
indutny/asn1.js#103

Support of JWK with x5c

Describe the bug

It looks like a library doesn't parse JWK consisting of x5c parameter without specific parameters like d and n . Though I cannot say for sure it's what expected by the RFC https://tools.ietf.org/html/rfc7517#section-4.7 , I would assume it's a bug since I found an expectations such JWK should be supported (https://github.com/auth0/node-jwks-rsa/blob/master/tests/mocks/jwks.js)

To Reproduce

Steps to reproduce the behaviour:

  1. Use JWK
{ alg: 'RS256',
    kty: 'RSA',
    use: 'sig',
    x5c:
     [ 'MIICsDCCAhmgAwIBAgIJAP0uzO56NPNDMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMTYwODAyMTIyMjMyWhcNMTYwOTAxMTIyMjMyWjBFMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdlatRjRjogo3WojgGHFHYLugdUWAY9iR3fy4arWNA1KoS8kVw33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQsHUfQrSDv+MuSUMAe8jzKE4qW+jK+xQU9a03GUnKHkkle+Q0pX/g6jXZ7r1/xAK5Do2kQ+X5xK9cipRgEKwIDAQABo4GnMIGkMB0GA1UdDgQWBBR7ZjPnt+i/E8VUy4tinxi0+H5vbTB1BgNVHSMEbjBsgBR7ZjPnt+i/E8VUy4tinxi0+H5vbaFJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAP0uzO56NPNDMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAnMA5ZAyEQgXrUl6JT/JFcg6HGXj9yTy71EEMVp3Md3B8WwDvs+di4JFcq8FKSoGtTY4Pb5WE9QVUAmwEsSQoETNYW3quRmYJCkpIHWnvUW/OAf2/Ejr6zXquhBC6WoCeKQuesMvo2qO1rStCUWahUh2/RQt9XozEWPWJ9Oe6a7c=' ],
    kid: '123' }
  1. Try jose.JWK.asKey(jwk).toPEM()
  2. Having an error key import failed. Most probably it fails here: https://github.com/panva/jose/blob/master/lib/jwk/import.js#L69 but I didn't debug that deep.

Expected behaviour
The method should not throw. The PEM from x5c could be parsed.

Environment:

  • jose version: [e.g. v2.0.2]
  • node version: [e.g. v10.0.19]

Additional context
Add any other context about the problem here.

It's related to failing tests on improving here: auth0/node-jwks-rsa#170

  • the bug is happening on latest jose too.
  • i have searched the issues tracker on github for similar issues and couldn't find anything related.

bug: KeyStore.toJWKS() doesn't exist in TS typings

KeyStore.toJWKS() method doesn't exist in TS typings.

Example code:

import { JWKS } from '@panva/jose';
const { KeyStore } = JWKS;
const keystore = new KeyStore();

keystore.toJWKS(true);

Environment:

  • @panva/jose version: v1.0.1
  • node version: v12.0.0

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.