diff --git a/.changesets/5n81r.minor.md b/.changesets/5n81r.minor.md new file mode 100644 index 00000000..2d67deba --- /dev/null +++ b/.changesets/5n81r.minor.md @@ -0,0 +1 @@ +Add Dribbble provider \ No newline at end of file diff --git a/README.md b/README.md index f02d0057..c1b98ac2 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ For a flexible OAuth 2.0 client, see [`oslo/oauth2`](http://github.com/pilcrowon - Box - Coinbase - Discord +- Dribbble - Dropbox - Facebook - Figma diff --git a/docs/malta.config.json b/docs/malta.config.json index c0aab8f7..d1c3cb9c 100644 --- a/docs/malta.config.json +++ b/docs/malta.config.json @@ -23,6 +23,7 @@ ["Box", "/providers/box"], ["Coinbase", "/providers/coinbase"], ["Discord", "/providers/discord"], + ["Dribbble", "/providers/dribbble"], ["Dropbox", "/providers/dropbox"], ["Facebook", "/providers/facebook"], ["Figma", "/providers/figma"], diff --git a/docs/pages/providers/dribbble.md b/docs/pages/providers/dribbble.md new file mode 100644 index 00000000..d7d74b46 --- /dev/null +++ b/docs/pages/providers/dribbble.md @@ -0,0 +1,35 @@ +--- +title: "Dribbble" +--- + +# Dribbble + +For usage, see [OAuth 2.0 provider](/guides/oauth2). + +```ts +import { Dribbble } from "arctic"; + +const dribbble = new Dribbble(clientId, clientSecret, redirectURI); +``` + +```ts +const url: URL = await dribbble.createAuthorizationURL(state, { + // optional + scopes +}); +const tokens: DribbbleTokens = await dribbble.validateAuthorizationCode(code); +``` + +## Get user profile + +Use the [`/user` endpoint](https://developer.dribbble.com/v2/user). + +```ts +const tokens = await dribbble.validateAuthorizationCode(code); +const response = await fetch("https://api.dribbble.com/v2/user", { + headers: { + Authorization: `Bearer ${tokens.accessToken}` + } +}); +const user = await response.json(); +``` diff --git a/src/index.ts b/src/index.ts index 580381b9..84aae3e1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,6 +6,7 @@ export { Bitbucket } from "./providers/bitbucket.js"; export { Box } from "./providers/box.js"; export { Coinbase } from "./providers/coinbase.js"; export { Discord } from "./providers/discord.js"; +export { Dribbble } from "./providers/dribbble.js"; export { Dropbox } from "./providers/dropbox.js"; export { Facebook } from "./providers/facebook.js"; export { Figma } from "./providers/figma.js"; @@ -45,6 +46,7 @@ export type { BitbucketTokens } from "./providers/bitbucket.js"; export type { BoxTokens } from "./providers/box.js"; export type { CoinbaseTokens } from "./providers/coinbase.js"; export type { DiscordTokens } from "./providers/discord.js"; +export type { DribbbleTokens } from "./providers/dribbble.js"; export type { DropboxRefreshedTokens, DropboxTokens } from "./providers/dropbox.js"; export type { FacebookTokens } from "./providers/facebook.js"; export type { FigmaRefreshedTokens, FigmaTokens } from "./providers/figma.js"; diff --git a/src/providers/dribbble.ts b/src/providers/dribbble.ts new file mode 100644 index 00000000..07140734 --- /dev/null +++ b/src/providers/dribbble.ts @@ -0,0 +1,45 @@ +import { OAuth2Client } from "oslo/oauth2"; + +import type { OAuth2Provider } from "../index.js"; + +const authorizeEndpoint = "https://dribbble.com/oauth/authorize"; +const tokenEndpoint = "https://dribbble.com/oauth/token"; + +export class Dribbble implements OAuth2Provider { + private client: OAuth2Client; + private clientSecret: string; + + constructor(clientId: string, clientSecret: string, redirectURI: string) { + this.client = new OAuth2Client(clientId, authorizeEndpoint, tokenEndpoint, { + redirectURI + }); + this.clientSecret = clientSecret; + } + + public async createAuthorizationURL( + state: string, + options?: { + scopes?: string[]; + } + ): Promise { + return await this.client.createAuthorizationURL({ + state, + scopes: options?.scopes ?? [] + }); + } + + public async validateAuthorizationCode(code: string): Promise { + const result = await this.client.validateAuthorizationCode(code, { + authenticateWith: "request_body", + credentials: this.clientSecret + }); + const tokens: DribbbleTokens = { + accessToken: result.access_token + }; + return tokens; + } +} + +export interface DribbbleTokens { + accessToken: string; +}