Skip to content

Commit

Permalink
rebuild
Browse files Browse the repository at this point in the history
  • Loading branch information
pilcrowonpaper committed Jul 12, 2024
1 parent f292061 commit 3eb7ef3
Show file tree
Hide file tree
Showing 49 changed files with 282 additions and 1,448 deletions.
11 changes: 0 additions & 11 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -1,17 +1,6 @@
module.exports = {
rules: {
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/ban-types": "off",
"@typescript-eslint/no-unused-vars": [
"error",
{
argsIgnorePattern: "^_",
varsIgnorePattern: "^_",
caughtErrorsIgnorePattern: "^_"
}
],
"@typescript-eslint/no-empty-interface": "off",
"@typescript-eslint/explicit-function-return-type": "error",
"no-async-promise-executor": "off",
"no-useless-catch": "off"
Expand Down
17 changes: 0 additions & 17 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,18 +1 @@
# @oslojs/oauth2

## 0.3.0

- [Breaking] Remove `setScopes()` and rename `appendScopes()` to `addScopes()`

## 0.2.0

- [Breaking] Remove APIs for sending requests
- Add `RequestResult`s

## 0.1.2

- Update dependencies.

## 0.1.1

- Fix: Add `Basic` prefix to encoded credentials in `authenticateWithHTTPBasicAuth()`
48 changes: 12 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,62 +2,38 @@

**Documentation: https://oauth2.oslojs.dev**

A JavaScript client library for OAuth 2.0 by [Oslo](https://oslojs.dev).
A small JavaScript library for parsing OAuth 2.0 token, token revocation, and device authorization responses by [Oslo](https://oslojs.dev).

Supports authorization code grant type, PKCE extension, refresh token grant type, token revocation, and device code grant type as specified in [RFC 6749](https://datatracker.ietf.org/doc/html/rfc6749), [RFC 7009](https://datatracker.ietf.org/doc/html/rfc7009), [RFC 7636](https://datatracker.ietf.org/doc/html/rfc7636), and [RFC 8628](https://datatracker.ietf.org/doc/html/rfc8628).
This package follows [RFC 6749](https://datatracker.ietf.org/doc/html/rfc6749), [RFC 7009](https://datatracker.ietf.org/doc/html/rfc7009), and [RFC 8628](https://datatracker.ietf.org/doc/html/rfc8628).

- Runtime-agnostic
- No third-party dependencies
- Fully typed

```ts
import { AuthorizationCodeTokenRequestContext, TokenRequestResult } from "@oslojs/oauth2";
import { TokenRequestResult } from "@oslojs/oauth2";

const context = new AuthorizationCodeTokenRequestContext(code);
context.authenticateWithHTTPBasicAuth(clientId, clientSecret);
context.setRedirectURI("https://my-app.com/login/callback");

const body = new URLSearchParams();
for (const [key, value] of context.body.entries()) {
body.set(key, value);
}
const response = await fetch("https://github.com/login/oauth/access_token", {
method: context.method,
method: "POST",
body,
headers: new Headers(context.headers)
headers
});
const data = await response.json();

if (typeof data !== "object" || data === null) {
throw new Error("Unexpected response");
}
const result = new TokenRequestResult(data);
if (result.hasErrorCode()) {
const error = result.errorCode();
} else {
const accessToken = result.accessToken();
const accessTokenExpiresAt = result.accessTokenExpiresAt();
const refreshToken = result.refreshToken();
throw new Error(`Request failed: ${error}`);
}
const accessToken = result.accessToken();
const accessTokenExpiresAt = result.accessTokenExpiresAt();
const refreshToken = result.refreshToken();
```

> Implicit grant type and resource owner password credentials grant type are not supported as they are no longer recommended.
## Installation

```
npm i @oslojs/oauth2
```

## Prerequisites

This package requires the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API). This is available in most modern runtimes, including Node.js 20+, Deno, Bun, and Cloudflare Workers. The major exception is Node.js 16 and 18. Make sure to polyfill it using `webcrypto`.

```ts
import { webcrypto } from "node:crypto";

globalThis.crypto = webcrypto;
```

Alternatively, add the `--experimental-global-webcrypto` flag when executing files.

```
node --experimental-global-webcrypto index.js
```
8 changes: 1 addition & 7 deletions docs/malta.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,7 @@
"sidebar": [
{
"title": "Examples",
"pages": [
["Authorization code grant type", "/examples/authorization-code"],
["PKCE", "/examples/pkce"],
["Refresh tokens", "/examples/refresh-token"],
["Token revocation", "/examples/token-revocation"],
["Device authorization grant type", "/examples/device-authorization"]
]
"pages": [["Parsing responses", "/examples/parse"]]
},
{
"title": "API reference",
Expand Down
87 changes: 0 additions & 87 deletions docs/pages/examples/authorization-code.md

This file was deleted.

96 changes: 0 additions & 96 deletions docs/pages/examples/device-authorization.md

This file was deleted.

79 changes: 79 additions & 0 deletions docs/pages/examples/parse.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
---
title: "Parsing responses"
---

# Parsing responses

## Access token and refresh token requests

Use `TokenRequestResult` for parsing access token and refresh token responses from the token endpoint. Methods like `accessToken()` will either return a value or throw an error if the field doesn't exist.

```ts
import { TokenRequestResult } from "@oslojs/oauth2";

const response = await fetch(accessTokenRequest);
const data = await response.json();
if (typeof data !== "object" || data === null) {
throw new Error("Unexpected response body");
}
const result = new TokenRequestResult(data);
if (result.hasErrorCode()) {
const error = result.errorCode();
throw new Error(`Failed to revoke token: ${error}`);
}
try {
const accessToken = result.accessToken();
const accessTokenExpiresAt = result.accessTokenExpiresAt();
const refreshToken = result.refreshToken();
} catch {
throw new Error("Failed to parse response");
}
```

## Token revocation requests

Since the token revocation endpoint returns an empty response when successful, use `OAuthRequestResult` directly.

```ts
import { OAuthRequestResult } from "@oslojs/oauth2";

const response = await fetch(tokenRevocationRequest);
if (!response.ok) {
const data = await response.json();
if (typeof data !== "object" || data === null) {
throw new Error("Unexpected response body");
}
const result = new OAuthRequestResult(data);
if (!result.hasErrorCode()) {
throw new Error("Unexpected response body");
}
const error = result.errorCode();
throw new Error(`Failed to revoke token: ${error}`);
}
```

## Device authorization requests

Use `DeviceAuthorizationRequestResult` for parsing device authorization responses. Methods like `deviceCode()` will either return a value or throw an error if the field doesn't exist.

```ts
import { DeviceAuthorizationRequestResult } from "@oslojs/oauth2";

const response = await fetch(deviceAuthorizationRequest);
const data = await response.json();
if (typeof data !== "object" || data === null) {
throw new Error("Unexpected response body");
}
const result = new DeviceAuthorizationRequestResult(data);
if (result.hasErrorCode()) {
const error = result.errorCode();
throw new Error(`Failed to revoke token: ${error}`);
}
try {
const deviceCode = result.deviceCode();
const userCode = result.userCode();
const codesExpireIn = result.codesExpireIn();
} catch {
throw new Error("Failed to parse response");
}
```
Loading

0 comments on commit 3eb7ef3

Please sign in to comment.