# atlassian-jwt

> JWT (JSON Web Token) implementation with custom Atlassian QSH claim verification

Latest version **2.0.3** (published 2023-12-13) · MIT license · 0 weekly downloads

> **Deprecated.** This package is deprecated.

## Install

```sh
npm install atlassian-jwt
pnpm add atlassian-jwt
yarn add atlassian-jwt
bun add atlassian-jwt
```

## Health

**Score 10/100 (F)** — status: deprecated.

Negative: deprecated.

## Facts

| | |
|---|---|
| Version | 2.0.3 |
| Published | 2023-12-13 |
| First published | 2016-05-18 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Node | >= 0.4.0 |
| Dependencies | 2 |
| Unpacked size | 29.5 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | Atlassian |
| Maintainers | jimihazelwood, mstaas, cwhittington, khanhfucius, puneetar, atlndao, hsong, fye3 |
| Keywords | jwt, qsh |

## Links

- npm: https://www.npmjs.com/package/atlassian-jwt
- Repository: http://bitbucket.org/atlassian/atlassian-jwt-js
- Homepage: https://bitbucket.org/atlassian/atlassian-jwt-js
- npm.io page: https://npm.io/package/atlassian-jwt

## Dependencies (2)

- [jsuri](https://npm.io/package/jsuri.md) ^1.3.1
- [lodash](https://npm.io/package/lodash.md) ^4.17.21

## Alternatives

- [@clerk/clerk-expo](https://npm.io/package/@clerk/clerk-expo.md) — 133.6K weekly downloads
- [@pothos/plugin-authz](https://npm.io/package/@pothos/plugin-authz.md) — 12.4K weekly downloads
- [@bounded-sh/client](https://npm.io/package/@bounded-sh/client.md) — 3.2K weekly downloads
- [@luigi-project/plugin-auth-oauth2](https://npm.io/package/@luigi-project/plugin-auth-oauth2.md) — 2.3K weekly downloads
- [@nocobase/plugin-verification](https://npm.io/package/@nocobase/plugin-verification.md) — 2.0K weekly downloads

## Recent versions

- 2.0.3 (latest) — 2023-12-13
- 2.0.2 — 2021-09-02
- 2.0.1 — 2021-06-03
- 2.0.0 — 2021-05-05
- 1.0.3 — 2020-04-05
- 1.0.2 — 2018-12-10
- 1.0.1 — 2018-08-24
- 0.1.5 — 2017-05-29
- 0.1.4 — 2017-03-16
- 0.1.3 — 2017-03-14
- 0.1.2 — 2017-02-15
- 0.1.1 — 2016-05-18
- 0.1.0 — 2016-05-18

## README

# atlassian-jwt

[![TypeScript](https://badges.frapsoft.com/typescript/code/typescript.svg?v=101)](https://github.com/ellerbrock/typescript-badges/)

[JWT (JSON Web Token)](http://self-issued.info/docs/draft-jones-json-web-token.html) encoding & decoding
library for node.js. Built on [jwt-simple](https://github.com/hokaccha/node-jwt-simple), it adds support
for Atlassian's custom QSH (query string hash) claim.

For more information on using JWT tokens with Atlassian apps, please read:
[Understanding JWT](https://developer.atlassian.com/cloud/jira/platform/understanding-jwt/).

## Install

```sh
npm install atlassian-jwt
```

## Usage

### Create a JWT token

```typescript
import * as jwt from 'atlassian-jwt';
import moment from 'moment';

const now = moment().utc();

// Simple form of [request](https://npmjs.com/package/request) object
const req: jwt.Request = jwt.fromMethodAndUrl('GET', '/rest/resource/you/want');

const tokenData = {
    "iss": 'issuer-val',
    "iat": now.unix(),                    // The time the token is generated
    "exp": now.add(3, 'minutes').unix(),  // Token expiry time (recommend 3 minutes after issuing)
    "qsh": jwt.createQueryStringHash(req) // [Query String Hash](https://developer.atlassian.com/cloud/jira/platform/understanding-jwt/#a-name-qsh-a-creating-a-query-string-hash)
};

const secret = 'xxx';

const token = jwt.encodeSymmetric(tokenData, secret);
console.log(token);
```

### Decode a JWT token

```typescript
const decoded = jwt.decodeSymmetric(token, secret);
console.log(decoded); //=> { foo: 'bar' }

// Decode without verifing the signature of the token.
// Don't do this unless that's your intention.
const decoded = jwt.decodeSymmetric(token, null, true);
console.log(decoded); //=> { foo: 'bar' }
```

### Miscellaneous Utilities

 - `jwt.createQueryStringHash(req, checkBodyForParams, baseUrl)`
   Creates a QSH using the algorithm defined by
   [the algorithm](https://developer.atlassian.com/static/connect/docs/latest/concepts/understanding-jwt.html#qsh).
 - `jwt.createCanonicalRequest(req, checkBodyForParams, baseUrl)`
   Creates a canonical request which is used to calculate the QSH for the JWT token.
   Prefer using `#createQueryStringHash()` directly.
 - `jwt.fromExpressRequest(expressRequest: ExpressRequest)`
   Converts an Express.js request into a `Request` object
   that can be used with other methods in this library.
 - `jwt.fromMethodAndUrl(method, url)`
   Takes in a method and URL, both as plain strings,
   and turns them into a `Request` object that can be used with other methods in this library.
 - `jwt.fromMethodAndPathAndBody(method, url, body)`
   Takes in a method, a URL, and some form params from a request body
   and turns them into a `Request` object that can be used with other methods in this library.
 - `jwt.getKeyId(token)`
   Extracts `kid` from a jwt token. 
 - `jwt.getAlgorithm(token)`
   Extracts `alg` from a jwt token. 
### Algorithms

By default the algorithm to encode is `HS256`.

The supported algorithms for encoding and decoding are `HS256`, `HS384`, `HS512`, and `RS256`.
See [Critical vulnerabilities in JSON Web Token libraries](https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/).

If you use TypeScript:

```typescript
// Encode using HS256 (default)
jwt.encodeSymmetric(payload, secret);

// Encode using HS512
jwt.encodeSymmetric(payload, secret, jwt.Algorithm.HS512);

// Encode using RS256, optinally accepts kid
jwt.encodeAsymmetric(payload, privateKey, jwt.Algorithm.RS256, { kid: 'f50f8562-f146-4b98-9bbb-7ce9545603b6' });

// Decode using RS256
jwt.decodeAsymmetric(token, publicKey, jwt.Algorithm.RS256);
```

If you use JavaScript:

```javascript
// Encode using HS256 (default)
jwt.encodeSymmetric(payload, secret);

// Encode using HS512
jwt.encodeSymmetric(payload, secret, 'HS512');

// Encode using RS256, optinally accepts kid
jwt.encodeAsymmetric(payload, privateKey, 'RS256', { kid: 'f50f8562-f146-4b98-9bbb-7ce9545603b6' });

// Decode using RS256
jwt.decodeAsymmetric(token, publicKey, 'RS256');
```

### Migrating from 0.1.x to 1.x.x

The `1.x.x` release brings some breaking changes, probably the most important change is that our methods no longer
accept the Express.js request object as an argument but instead use our own intermediate `Request` object.

A convenience method called `fromExpressRequest` has been written to ease the transition. You can use it like so:

```typescript
import * as jwt from 'atlassian-jwt';
import { Request as ExpressRequest } from 'express';

const eReq: ExpressRequest = ...;
const qsh = jwt.createQueryStringHash(jwt.fromExpressRequest(eReq));
```

Other methods, like `fromMethodAndUrl` and `fromMethodAndPathAndBody` were written to allow easier generation of
`Request` objects from other libraries.

### Migrating from 1.x.x to 2.x.x

The `2.x.x` release supports `RS256` asymmetric algorithm which can be used with `encodeAsymmetric` and `decodeAsymmetric` functions.
`encode` and `decode` functions in `1.x.x` are renamed to `encodeSymmetric` and `decodeSymmetric` which supports symmetric algorithms only.

## Guides for developers

### Publishing this library

Update `version` in package.json and lib/jwt.ts.

To publish this library:

```sh
npm run tsc
npm publish
```

This has been combined into a single command with:

```sh
npm run build-and-publish
```

Only the built TypeScript files will be published with this library.

---
_Source: https://npm.io/package/atlassian-jwt · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
