-
-
Notifications
You must be signed in to change notification settings - Fork 87
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6ab0262
commit afd45a5
Showing
5 changed files
with
151 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
--- | ||
title: "Start.gg" | ||
--- | ||
|
||
# Start.gg | ||
|
||
OAuth 2.0 provider for Start.gg. | ||
|
||
Also see the [OAuth 2.0](/guides/oauth2) guide. | ||
|
||
## Initialization | ||
|
||
```ts | ||
import { StartGG } from "arctic"; | ||
|
||
const startgg = new StartGG(clientId, clientSecret, redirectURI); | ||
``` | ||
|
||
## Create authorization URL | ||
|
||
```ts | ||
import { generateState } from "arctic"; | ||
|
||
const state = generateState(); | ||
const scopes = ["user.identity", "user.email"]; | ||
const url = startgg.createAuthorizationURL(state, scopes); | ||
``` | ||
|
||
## Validate authorization code | ||
|
||
Start.gg requires a list of scopes in addition to the authorization code. `validateAuthorizationCode()` will either return an [`OAuth2Tokens`](/reference/main/OAuth2Tokens), or throw one of [`OAuth2RequestError`](/reference/main/OAuth2RequestError), [`ArcticFetchError`](/reference/main/ArcticFetchError), or a standard `Error` (parse errors). Start.gg returns an access token, the access token expiration, and a refresh token. | ||
|
||
```ts | ||
import { OAuth2RequestError, ArcticFetchError } from "arctic"; | ||
|
||
try { | ||
const tokens = await startgg.validateAuthorizationCode(code, scopes); | ||
const accessToken = tokens.accessToken(); | ||
const accessTokenExpiresAt = tokens.accessTokenExpiresAt(); | ||
const refreshToken = tokens.refreshToken(); | ||
} catch (e) { | ||
if (e instanceof OAuth2RequestError) { | ||
// Invalid authorization code, credentials, or redirect URI | ||
const code = e.code; | ||
// ... | ||
} | ||
if (e instanceof ArcticFetchError) { | ||
// Failed to call `fetch()` | ||
const cause = e.cause; | ||
// ... | ||
} | ||
// Parse error | ||
} | ||
``` | ||
|
||
## Refresh access tokens | ||
|
||
Use `refreshAccessToken()` to get a new access token using a refresh token. Start.gg returns the same values as during the authorization code validation. This method also returns `OAuth2Tokens` and throws the same errors as `validateAuthorizationCode()` | ||
|
||
```ts | ||
import { OAuth2RequestError, ArcticFetchError } from "arctic"; | ||
|
||
try { | ||
const tokens = await startgg.refreshAccessToken(accessToken, scopes); | ||
const accessToken = tokens.accessToken(); | ||
const accessTokenExpiresAt = tokens.accessTokenExpiresAt(); | ||
const refreshToken = tokens.refreshToken(); | ||
} catch (e) { | ||
if (e instanceof OAuth2RequestError) { | ||
// Invalid authorization code, credentials, or redirect URI | ||
} | ||
if (e instanceof ArcticFetchError) { | ||
// Failed to call `fetch()` | ||
} | ||
// Parse error | ||
} | ||
``` | ||
|
||
## Get user profile | ||
|
||
Add the `user.identity` scope and optionally the `user.email` to get the user email. See the [Start.gg Schema](https://developer.start.gg/reference/user.doc). | ||
|
||
```ts | ||
const response = await fetch("https://api.start.gg/gql/alpha", { | ||
method: "POST", | ||
body: `{"query": "{ currentUser {id slug email player { gamerTag } } }" }`, | ||
headers: { | ||
"Content-type": "application/json", | ||
Authorization: `Bearer ${accessToken}` | ||
} | ||
}); | ||
const result = await response.json(); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import { createOAuth2Request, sendTokenRequest } from "../request.js"; | ||
|
||
import type { OAuth2Tokens } from "../oauth2.js"; | ||
|
||
const authorizationEndpoint = "https://start.gg/oauth/authoriz"; | ||
const tokenEndpoint = "https://api.start.gg/oauth/access_token"; | ||
const refreshEndpoint = "https://api.start.gg/oauth/refresh"; | ||
|
||
export class StartGG { | ||
private clientId: string; | ||
private clientSecret: string; | ||
private redirectURI: string; | ||
|
||
constructor(clientId: string, clientSecret: string, redirectURI: string) { | ||
this.clientId = clientId; | ||
this.clientSecret = clientSecret; | ||
this.redirectURI = redirectURI; | ||
} | ||
|
||
public createAuthorizationURL(state: string, scopes: string[]): URL { | ||
const url = new URL(authorizationEndpoint); | ||
url.searchParams.set("response_type", "code"); | ||
url.searchParams.set("client_id", this.clientId); | ||
url.searchParams.set("state", state); | ||
url.searchParams.set("scope", scopes.join(" ")); | ||
url.searchParams.set("redirect_uri", this.redirectURI); | ||
return url; | ||
} | ||
|
||
public async validateAuthorizationCode(code: string, scopes: string[]): Promise<OAuth2Tokens> { | ||
const body = new URLSearchParams(); | ||
body.set("grant_type", "authorization_code"); | ||
body.set("code", code); | ||
body.set("redirect_uri", this.redirectURI); | ||
body.set("client_id", this.clientId); | ||
body.set("client_secret", this.clientSecret); | ||
body.set("scope", scopes.join(" ")); | ||
const request = createOAuth2Request(tokenEndpoint, body); | ||
const tokens = await sendTokenRequest(request); | ||
return tokens; | ||
} | ||
|
||
public async refreshAccessToken(refreshToken: string, scopes: string[]): Promise<OAuth2Tokens> { | ||
const body = new URLSearchParams(); | ||
body.set("grant_type", "refresh_token"); | ||
body.set("refresh_token", refreshToken); | ||
body.set("redirect_uri", this.redirectURI); | ||
body.set("client_id", this.clientId); | ||
body.set("client_secret", this.clientSecret); | ||
body.set("scope", scopes.join(" ")); | ||
const request = createOAuth2Request(refreshEndpoint, body); | ||
const tokens = await sendTokenRequest(request); | ||
return tokens; | ||
} | ||
} |