|
1 | | -import { OAuth2Client, CodeChallengeMethod } from "../client.js"; |
| 1 | +import { createS256CodeChallenge } from "../oauth2.js"; |
| 2 | +import { createOAuth2Request, sendTokenRequest, sendTokenRevocationRequest } from "../request.js"; |
2 | 3 |
|
3 | 4 | import type { OAuth2Tokens } from "../oauth2.js"; |
4 | 5 |
|
5 | 6 | const authorizationEndpoint = "https://polar.sh/oauth2/authorize"; |
6 | 7 | const tokenEndpoint = "https://api.polar.sh/v1/oauth2/token"; |
7 | 8 | const tokenRevocationEndpoint = "https://api.polar.sh/v1/oauth2/revoke"; |
8 | 9 |
|
| 10 | +// Polar.sh supports HTTP Basic Auth but `client_secret` is set as the default authentication method. |
9 | 11 | export class Polar { |
10 | | - private client: OAuth2Client; |
| 12 | + private clientId: string; |
| 13 | + private clientSecret: string | null; |
| 14 | + private redirectURI: string; |
11 | 15 |
|
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; |
14 | 20 | } |
15 | 21 |
|
16 | 22 | 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"); |
24 | 34 | return url; |
25 | 35 | } |
26 | 36 |
|
27 | 37 | public async validateAuthorizationCode( |
28 | 38 | code: string, |
29 | 39 | codeVerifier: string |
30 | 40 | ): 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); |
32 | 52 | return tokens; |
33 | 53 | } |
34 | 54 |
|
35 | 55 | 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); |
37 | 65 | return tokens; |
38 | 66 | } |
39 | 67 |
|
40 | 68 | 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); |
42 | 73 | } |
43 | 74 | } |
0 commit comments