Skip to content

Commit 641aaf6

Browse files
Merge pull request #287 from pilcrowonpaper/next
Release v3.5.0
2 parents 92f61fe + 057cbe0 commit 641aaf6

File tree

3 files changed

+48
-15
lines changed

3 files changed

+48
-15
lines changed

.RELEASE.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- Polar.sh: Fix client authentication ([#286](https://github.com/pilcrowonpaper/arctic/pull/286)).
2+
- Polar.sh: Support public clients ([#286](https://github.com/pilcrowonpaper/arctic/pull/286)).

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "arctic",
33
"type": "module",
4-
"version": "3.4.0",
4+
"version": "3.5.0",
55
"description": "OAuth 2.0 clients for popular providers",
66
"main": "dist/index.js",
77
"types": "dist/index.d.ts",

src/providers/polar.ts

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,74 @@
1-
import { OAuth2Client, CodeChallengeMethod } from "../client.js";
1+
import { createS256CodeChallenge } from "../oauth2.js";
2+
import { createOAuth2Request, sendTokenRequest, sendTokenRevocationRequest } from "../request.js";
23

34
import type { OAuth2Tokens } from "../oauth2.js";
45

56
const authorizationEndpoint = "https://polar.sh/oauth2/authorize";
67
const tokenEndpoint = "https://api.polar.sh/v1/oauth2/token";
78
const tokenRevocationEndpoint = "https://api.polar.sh/v1/oauth2/revoke";
89

10+
// Polar.sh supports HTTP Basic Auth but `client_secret` is set as the default authentication method.
911
export class Polar {
10-
private client: OAuth2Client;
12+
private clientId: string;
13+
private clientSecret: string | null;
14+
private redirectURI: string;
1115

12-
constructor(clientId: string, clientSecret: string, redirectURI: string) {
13-
this.client = new OAuth2Client(clientId, clientSecret, redirectURI);
16+
constructor(clientId: string, clientSecret: string | null, redirectURI: string) {
17+
this.clientId = clientId;
18+
this.clientSecret = clientSecret;
19+
this.redirectURI = redirectURI;
1420
}
1521

1622
public createAuthorizationURL(state: string, codeVerifier: string, scopes: string[]): URL {
17-
const url = this.client.createAuthorizationURLWithPKCE(
18-
authorizationEndpoint,
19-
state,
20-
CodeChallengeMethod.S256,
21-
codeVerifier,
22-
scopes
23-
);
23+
const url = new URL(authorizationEndpoint);
24+
url.searchParams.set("client_id", this.clientId);
25+
url.searchParams.set("response_type", "code");
26+
url.searchParams.set("redirect_uri", this.redirectURI);
27+
url.searchParams.set("state", state);
28+
if (scopes.length > 0) {
29+
url.searchParams.set("scope", scopes.join(" "));
30+
}
31+
const codeChallenge = createS256CodeChallenge(codeVerifier);
32+
url.searchParams.set("code_challenge", codeChallenge);
33+
url.searchParams.set("code_challenge_method", "S256");
2434
return url;
2535
}
2636

2737
public async validateAuthorizationCode(
2838
code: string,
2939
codeVerifier: string
3040
): Promise<OAuth2Tokens> {
31-
const tokens = await this.client.validateAuthorizationCode(tokenEndpoint, code, codeVerifier);
41+
const body = new URLSearchParams();
42+
body.set("code", code);
43+
body.set("client_id", this.clientId);
44+
if (this.clientSecret !== null) {
45+
body.set("client_secret", this.clientSecret);
46+
}
47+
body.set("redirect_uri", this.redirectURI);
48+
body.set("grant_type", "authorization_code");
49+
body.set("code_verifier", codeVerifier);
50+
const request = createOAuth2Request(tokenEndpoint, body);
51+
const tokens = await sendTokenRequest(request);
3252
return tokens;
3353
}
3454

3555
public async refreshAccessToken(refreshToken: string): Promise<OAuth2Tokens> {
36-
const tokens = await this.client.refreshAccessToken(tokenEndpoint, refreshToken, []);
56+
const body = new URLSearchParams();
57+
body.set("refresh_token", refreshToken);
58+
body.set("client_id", this.clientId);
59+
if (this.clientSecret !== null) {
60+
body.set("client_secret", this.clientSecret);
61+
}
62+
body.set("grant_type", "refresh_token");
63+
const request = createOAuth2Request(tokenEndpoint, body);
64+
const tokens = await sendTokenRequest(request);
3765
return tokens;
3866
}
3967

4068
public async revokeToken(token: string): Promise<void> {
41-
await this.client.revokeToken(tokenRevocationEndpoint, token);
69+
const body = new URLSearchParams();
70+
body.set("token", token);
71+
const request = createOAuth2Request(tokenRevocationEndpoint, body);
72+
await sendTokenRevocationRequest(request);
4273
}
4374
}

0 commit comments

Comments
 (0)