@oslojs/oauth2
Advanced tools
Comparing version 0.3.0 to 0.4.0
@@ -1,6 +0,30 @@ | ||
export { AuthorizationCodeTokenRequestContext, AuthorizationCodeAuthorizationURL, generateCodeVerifier, generateState } from "./authorization-code.js"; | ||
export { DeviceAuthorizationRequestContext, DeviceAuthorizationTokenRequestContext, DeviceAuthorizationRequestResult } from "./device-authorization.js"; | ||
export { TokenRevocationRequestContext, TokenType } from "./token-revocation.js"; | ||
export { RefreshRequestContext } from "./refresh-token.js"; | ||
export { OAuth2RequestContext, OAuth2RequestResult } from "./request.js"; | ||
export { TokenRequestResult } from "./token.js"; | ||
export declare class OAuthRequestErrorResult { | ||
body: object; | ||
constructor(body: object); | ||
hasErrorCode(): boolean; | ||
errorCode(): string; | ||
hasErrorDescription(): boolean; | ||
errorDescription(): string; | ||
hasErrorURI(): boolean; | ||
errorURI(): string; | ||
hasState(): boolean; | ||
state(): string; | ||
} | ||
export declare class TokenRequestResult extends OAuthRequestErrorResult { | ||
tokenType(): string; | ||
accessToken(): string; | ||
accessTokenExpiresInSeconds(): number; | ||
accessTokenExpiresAt(): Date; | ||
hasRefreshToken(): boolean; | ||
refreshToken(): string; | ||
hasScopes(): boolean; | ||
scopes(): string[]; | ||
} | ||
export declare class DeviceAuthorizationRequestResult extends OAuthRequestErrorResult { | ||
deviceCode(): string; | ||
userCode(): string; | ||
verificationURI(): string; | ||
codesExpireInSeconds(): number; | ||
codesExpireAt(): Date; | ||
intervalSeconds(): number; | ||
} |
@@ -1,6 +0,121 @@ | ||
export { AuthorizationCodeTokenRequestContext, AuthorizationCodeAuthorizationURL, generateCodeVerifier, generateState } from "./authorization-code.js"; | ||
export { DeviceAuthorizationRequestContext, DeviceAuthorizationTokenRequestContext, DeviceAuthorizationRequestResult } from "./device-authorization.js"; | ||
export { TokenRevocationRequestContext, TokenType } from "./token-revocation.js"; | ||
export { RefreshRequestContext } from "./refresh-token.js"; | ||
export { OAuth2RequestContext, OAuth2RequestResult } from "./request.js"; | ||
export { TokenRequestResult } from "./token.js"; | ||
export class OAuthRequestErrorResult { | ||
body; | ||
constructor(body) { | ||
this.body = body; | ||
} | ||
hasErrorCode() { | ||
return "error" in this.body && typeof this.body.error === "string"; | ||
} | ||
errorCode() { | ||
if ("error" in this.body && typeof this.body.error === "string") { | ||
return this.body.error; | ||
} | ||
throw new Error("Missing or invalid 'error' field"); | ||
} | ||
hasErrorDescription() { | ||
return "error_description" in this.body && typeof this.body.error_description === "string"; | ||
} | ||
errorDescription() { | ||
if ("error_description" in this.body && typeof this.body.error_description === "string") { | ||
return this.body.error_description; | ||
} | ||
throw new Error("Missing or invalid 'error_description' field"); | ||
} | ||
hasErrorURI() { | ||
return "error_uri" in this.body && typeof this.body.error_uri === "string"; | ||
} | ||
errorURI() { | ||
if ("error_uri" in this.body && typeof this.body.error_uri === "string") { | ||
return this.body.error_uri; | ||
} | ||
throw new Error("Missing or invalid 'error_uri' field"); | ||
} | ||
hasState() { | ||
return "state" in this.body && typeof this.body.state === "string"; | ||
} | ||
state() { | ||
if ("state" in this.body && typeof this.body.state === "string") { | ||
return this.body.state; | ||
} | ||
throw new Error("Missing or invalid 'state' field"); | ||
} | ||
} | ||
export class TokenRequestResult extends OAuthRequestErrorResult { | ||
tokenType() { | ||
if ("token_type" in this.body && typeof this.body.token_type === "string") { | ||
return this.body.token_type; | ||
} | ||
throw new Error("Missing or invalid 'token_type' field"); | ||
} | ||
accessToken() { | ||
if ("access_token" in this.body && typeof this.body.access_token === "string") { | ||
return this.body.access_token; | ||
} | ||
throw new Error("Missing or invalid 'access_token' field"); | ||
} | ||
accessTokenExpiresInSeconds() { | ||
if ("expires_in" in this.body && typeof this.body.expires_in === "number") { | ||
return this.body.expires_in; | ||
} | ||
throw new Error("Missing or invalid 'expires_in' field"); | ||
} | ||
accessTokenExpiresAt() { | ||
return new Date(Date.now() + this.accessTokenExpiresInSeconds() * 1000); | ||
} | ||
hasRefreshToken() { | ||
return "refresh_token" in this.body && typeof this.body.refresh_token === "string"; | ||
} | ||
refreshToken() { | ||
if ("refresh_token" in this.body && typeof this.body.refresh_token === "string") { | ||
return this.body.refresh_token; | ||
} | ||
throw new Error("Missing or invalid 'refresh_token' field"); | ||
} | ||
hasScopes() { | ||
return "scope" in this.body && typeof this.body.scope === "string"; | ||
} | ||
scopes() { | ||
if ("scope" in this.body && typeof this.body.scope === "string") { | ||
return this.body.scope.split(" "); | ||
} | ||
throw new Error("Missing or invalid 'scope' field"); | ||
} | ||
} | ||
export class DeviceAuthorizationRequestResult extends OAuthRequestErrorResult { | ||
deviceCode() { | ||
if ("device_code" in this.body && typeof this.body.device_code === "string") { | ||
return this.body.device_code; | ||
} | ||
throw new Error("Missing or invalid 'device_code' field"); | ||
} | ||
userCode() { | ||
if ("user_code" in this.body && typeof this.body.user_code === "string") { | ||
return this.body.user_code; | ||
} | ||
throw new Error("Missing or invalid 'user_code' field"); | ||
} | ||
verificationURI() { | ||
if ("verification_uri" in this.body && typeof this.body.verification_uri === "string") { | ||
return this.body.verification_uri; | ||
} | ||
throw new Error("Missing or invalid 'verification_uri' field"); | ||
} | ||
codesExpireInSeconds() { | ||
if ("expires_in" in this.body && typeof this.body.expires_in === "number") { | ||
return this.body.expires_in; | ||
} | ||
throw new Error("Missing or invalid 'expires_in' field"); | ||
} | ||
codesExpireAt() { | ||
return new Date(Date.now() + this.codesExpireInSeconds() * 1000); | ||
} | ||
intervalSeconds() { | ||
if ("interval" in this.body) { | ||
if (typeof this.body.interval === "number") { | ||
return this.body.interval; | ||
} | ||
throw new Error("Invalid 'interval' field"); | ||
} | ||
return 5; | ||
} | ||
} |
{ | ||
"name": "@oslojs/oauth2", | ||
"type": "module", | ||
"version": "0.3.0", | ||
"version": "0.4.0", | ||
"description": "A runtime-agnostic OAuth 2.0 library", | ||
@@ -32,6 +32,2 @@ "main": "dist/index.js", | ||
}, | ||
"dependencies": { | ||
"@oslojs/crypto": "0.2.0", | ||
"@oslojs/encoding": "0.3.0" | ||
}, | ||
"scripts": { | ||
@@ -38,0 +34,0 @@ "build": "rm -rf dist/* && tsc --project tsconfig.build.json", |
@@ -5,5 +5,5 @@ # @oslojs/oauth2 | ||
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). | ||
@@ -15,31 +15,23 @@ - Runtime-agnostic | ||
```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 | ||
@@ -50,17 +42,1 @@ | ||
``` | ||
## 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 | ||
``` |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
0
8349
5
151
40
1
- Removed@oslojs/crypto@0.2.0
- Removed@oslojs/encoding@0.3.0
- Removed@oslojs/binary@0.2.0(transitive)
- Removed@oslojs/crypto@0.2.0(transitive)
- Removed@oslojs/encoding@0.3.0(transitive)