From da703766d73b7ca601d0cb01d31582751c5d35f0 Mon Sep 17 00:00:00 2001 From: Hernan Alvarado Date: Wed, 22 Jan 2025 15:14:57 -0500 Subject: [PATCH 1/5] feat(provider): add Figma provider --- .github/ISSUE_TEMPLATE/2_bug_provider.yml | 1 + docs/pages/data/manifest.json | 1 + .../pages/getting-started/providers/figma.mdx | 134 ++++++++++++++++++ docs/public/img/providers/figma.svg | 7 + packages/core/src/providers/figma.ts | 127 +++++++++++++++++ 5 files changed, 270 insertions(+) create mode 100644 docs/pages/getting-started/providers/figma.mdx create mode 100644 docs/public/img/providers/figma.svg create mode 100644 packages/core/src/providers/figma.ts diff --git a/.github/ISSUE_TEMPLATE/2_bug_provider.yml b/.github/ISSUE_TEMPLATE/2_bug_provider.yml index 4545ebbf3e..c8973ed186 100644 --- a/.github/ISSUE_TEMPLATE/2_bug_provider.yml +++ b/.github/ISSUE_TEMPLATE/2_bug_provider.yml @@ -49,6 +49,7 @@ body: - "EVE Online" - "Facebook" - "FACEIT" + - "Figma" - "Foursquare" - "Freshbooks" - "FusionAuth" diff --git a/docs/pages/data/manifest.json b/docs/pages/data/manifest.json index 50fb339f1c..89508b5389 100644 --- a/docs/pages/data/manifest.json +++ b/docs/pages/data/manifest.json @@ -73,6 +73,7 @@ "duende-identityserver-6": "DuendeIdentityServer6", "eveonline": "EVE Online", "faceit": "FACEIT", + "figma": "Figma", "foursquare": "Foursquare", "freshbooks": "Freshbooks", "fusionauth": "FusionAuth", diff --git a/docs/pages/getting-started/providers/figma.mdx b/docs/pages/getting-started/providers/figma.mdx new file mode 100644 index 0000000000..8198b8b155 --- /dev/null +++ b/docs/pages/getting-started/providers/figma.mdx @@ -0,0 +1,134 @@ +import { Code } from "@/components/Code" +import { Callout } from "nextra/components" + + + +# Figma Provider + +## Resources + +- [Using OAuth 2 on Figma](https://www.figma.com/developers/api#oauth2) +- [User Type](https://www.figma.com/developers/api#users-types) +- [Scopes](https://www.figma.com/developers/api#authentication-scopes) +- [Migrate](https://www.figma.com/developers/api#oauth_migration_guide) + +## Setup + +### Callback URL + + + + +```bash +https://example.com/api/auth/callback/figma +``` + + + + +```bash +https://example.com/auth/callback/figma +``` + + + + +```bash +https://example.com/auth/callback/figma +``` + + + + +### Environment Variables + + + + +```bash filename=".env.local" +AUTH_FIGMA_ID +AUTH_FIGMA_SECRET +``` + + + + +```bash filename=".env" +AUTH_FIGMA_ID +AUTH_FIGMA_SECRET +``` + + + + +```bash filename=".env" +AUTH_FIGMA_ID +AUTH_FIGMA_SECRET +``` + + + + +```bash filename=".env" +AUTH_FIGMA_ID +AUTH_FIGMA_SECRET +``` + + + + +### Configuration + + + + +```ts filename="@/auth.ts" +import NextAuth from "next-auth" +import Bitbucket from "next-auth/providers/bitbucket" +export const { handlers, auth, signIn, signOut } = NextAuth({ + providers: [Bitbucket], +}) +``` + + + + +```ts filename="/src/routes/plugin@auth.ts" +import { QwikAuth$ } from "@auth/qwik" +import Bitbucket from "@auth/qwik/providers/bitbucket" +export const { onRequest, useSession, useSignIn, useSignOut } = QwikAuth$( + () => ({ + providers: [Bitbucket], + }) +) +``` + + + + +```ts filename="/src/auth.ts" +import { SvelteKitAuth } from "@auth/sveltekit" +import Bitbucket from "@auth/sveltekit/providers/bitbucket" +export const { handle, signIn, signOut } = SvelteKitAuth({ + providers: [Bitbucket], +}) +``` + + + + +```ts filename="/src/app.ts" +import { ExpressAuth } from "@auth/express" +import Bitbucket from "@auth/express/providers/bitbucket" +app.use("/auth/*", ExpressAuth({ providers: [Bitbucket] })) +``` + + + + + + The URL must be accessed via the user's browser and not an embedded webview + inside your application. Webview access to the Figma OAuth flow is not + supported and may stop working for some or all users without an API version + update. + diff --git a/docs/public/img/providers/figma.svg b/docs/public/img/providers/figma.svg new file mode 100644 index 0000000000..bd81186e9b --- /dev/null +++ b/docs/public/img/providers/figma.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/packages/core/src/providers/figma.ts b/packages/core/src/providers/figma.ts new file mode 100644 index 0000000000..7c32aa4728 --- /dev/null +++ b/packages/core/src/providers/figma.ts @@ -0,0 +1,127 @@ +/** + *
+ * Built-in Figma integration. + * + * + * + *
+ * + * @module providers/discord + */ +import { OAuth2Config, OAuthUserConfig } from "./index.js" + +/** + * @see https://www.figma.com/developers/api#users-types + */ +interface FigmaProfile { + id: string + email: string + handle: string + img_url: string +} + +/** + * ### Setup + * + * #### Callback URL + * + * ```ts + * https://example.com/api/auth/callback/figma + * ``` + * + * #### Configuration + * + * ```ts + * import { Auth } from "@auth/core" + * import Figma from "@auth/core/providers/figma" + * + * const request = new Request(origin) + * const response = await Auth(request, { + * providers: [ + * Figma({ + * clientId: process.env.BITBUCKET_CLIENT_ID, + * clientSecret: process.env.BITBUCKET_CLIENT_SECRET + * }) + * ], + * }) + * ``` + * + * ### Resources + * + * - [Using OAuth 2 on Figma](https://www.figma.com/developers/api#oauth2) + * - [User Type](https://www.figma.com/developers/api#users-types) + * - [Scopes](https://www.figma.com/developers/api#authentication-scopes) + * - [Migrate](https://www.figma.com/developers/api#oauth_migration_guide) + * + * #### Notes + * + * By default, Auth.js assumes that the Figma provider is based on the [OAuth 2](https://www.rfc-editor.org/rfc/rfc6749.html) specification. + * + * :::tip + * + * The Bitbucket provider comes with a [default configuration](https://github.com/nextauthjs/next-auth/blob/main/packages/core/src/providers/bitbucket.ts). + * To override the defaults for your use case, check out [customizing a built-in OAuth provider](https://authjs.dev/guides/configuring-oauth-providers). + * + * ::: + * + * :::info **Disclaimer** + * + * If you think you found a bug in the default configuration, you can [open an issue](https://authjs.dev/new/provider-issue). + * + * Auth.js strictly adheres to the specification and it cannot take responsibility for any deviation from + * the spec by the provider. You can open an issue, but if the problem is non-compliance with the spec, + * we might not pursue a resolution. You can ask for more help in [Discussions](https://authjs.dev/new/github-discussions). + * + * ::: + */ +export default function Figma( + options: OAuthUserConfig +): OAuth2Config { + const bytes = crypto.getRandomValues(new Uint8Array(16)) + const state = Buffer.from(bytes).toString("base64") + return { + id: "figma", + name: "Figma", + type: "oauth", + authorization: { + url: "https://www.figma.com/oauth", + params: { + scope: "files:read", + state, + }, + }, + token: { + url: "https://api.figma.com/v1/oauth/token", + async request({ params, provider }: any) { + return await fetch(provider.token.url, { + method: "POST", + headers: { + "Content-Type": "application/x-www-form-urlencoded", + Authorization: `Basic ${Buffer.from( + `${options.clientId}:${options.clientSecret}` + ).toString("base64")}`, + }, + body: new URLSearchParams({ + code: params.code, + grant_type: "authorization_code", + redirect_uri: options.redirectProxyUrl!, + }).toString(), + }).then((response) => response.json()) + }, + }, + userinfo: "https://api.figma.com/v1/me", + profile(profile) { + return { + name: profile.handle, + email: profile.email, + id: profile.id, + image: profile.img_url, + } + }, + style: { + text: "#fff", + bg: "#ff7237", + }, + options, + } +} From dc2b22951918d0d45ba394bbad555a38d930e81f Mon Sep 17 00:00:00 2001 From: Hernan Alvarado Date: Wed, 22 Jan 2025 15:19:08 -0500 Subject: [PATCH 2/5] chore: update environment variables --- packages/core/src/providers/figma.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/core/src/providers/figma.ts b/packages/core/src/providers/figma.ts index 7c32aa4728..1674619f99 100644 --- a/packages/core/src/providers/figma.ts +++ b/packages/core/src/providers/figma.ts @@ -6,7 +6,7 @@ * * * - * @module providers/discord + * @module providers/figma */ import { OAuth2Config, OAuthUserConfig } from "./index.js" @@ -39,8 +39,8 @@ interface FigmaProfile { * const response = await Auth(request, { * providers: [ * Figma({ - * clientId: process.env.BITBUCKET_CLIENT_ID, - * clientSecret: process.env.BITBUCKET_CLIENT_SECRET + * clientId: process.env.AUTH_FIGMA_ID, + * clientSecret: process.env.AUTH_FIGMA_SECRET * }) * ], * }) From 579c42f4ed6a26384300c1c310607e6aed2910b7 Mon Sep 17 00:00:00 2001 From: Falco Winkler <8613031+falcowinkler@users.noreply.github.com> Date: Sat, 25 Jan 2025 09:53:36 +0100 Subject: [PATCH 3/5] fix docs referencing bitbucket --- docs/pages/getting-started/providers/figma.mdx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/pages/getting-started/providers/figma.mdx b/docs/pages/getting-started/providers/figma.mdx index 8198b8b155..160e3e3b38 100644 --- a/docs/pages/getting-started/providers/figma.mdx +++ b/docs/pages/getting-started/providers/figma.mdx @@ -84,9 +84,9 @@ AUTH_FIGMA_SECRET ```ts filename="@/auth.ts" import NextAuth from "next-auth" -import Bitbucket from "next-auth/providers/bitbucket" +import Figma from "next-auth/providers/figma" export const { handlers, auth, signIn, signOut } = NextAuth({ - providers: [Bitbucket], + providers: [Figma], }) ``` @@ -95,10 +95,10 @@ export const { handlers, auth, signIn, signOut } = NextAuth({ ```ts filename="/src/routes/plugin@auth.ts" import { QwikAuth$ } from "@auth/qwik" -import Bitbucket from "@auth/qwik/providers/bitbucket" +import Figma from "@auth/qwik/providers/figma" export const { onRequest, useSession, useSignIn, useSignOut } = QwikAuth$( () => ({ - providers: [Bitbucket], + providers: [Figma], }) ) ``` @@ -108,9 +108,9 @@ export const { onRequest, useSession, useSignIn, useSignOut } = QwikAuth$( ```ts filename="/src/auth.ts" import { SvelteKitAuth } from "@auth/sveltekit" -import Bitbucket from "@auth/sveltekit/providers/bitbucket" +import Figma from "@auth/sveltekit/providers/figma" export const { handle, signIn, signOut } = SvelteKitAuth({ - providers: [Bitbucket], + providers: [Figma], }) ``` @@ -119,8 +119,8 @@ export const { handle, signIn, signOut } = SvelteKitAuth({ ```ts filename="/src/app.ts" import { ExpressAuth } from "@auth/express" -import Bitbucket from "@auth/express/providers/bitbucket" -app.use("/auth/*", ExpressAuth({ providers: [Bitbucket] })) +import Figma from "@auth/express/providers/figma" +app.use("/auth/*", ExpressAuth({ providers: [Figma] })) ``` From 6f91c0f735360539c9345edfbae53565db820b96 Mon Sep 17 00:00:00 2001 From: Falco Winkler <8613031+falcowinkler@users.noreply.github.com> Date: Sat, 25 Jan 2025 09:53:59 +0100 Subject: [PATCH 4/5] simplify provider --- packages/core/src/providers/figma.ts | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/packages/core/src/providers/figma.ts b/packages/core/src/providers/figma.ts index 1674619f99..eddd2d2f6e 100644 --- a/packages/core/src/providers/figma.ts +++ b/packages/core/src/providers/figma.ts @@ -49,9 +49,7 @@ interface FigmaProfile { * ### Resources * * - [Using OAuth 2 on Figma](https://www.figma.com/developers/api#oauth2) - * - [User Type](https://www.figma.com/developers/api#users-types) * - [Scopes](https://www.figma.com/developers/api#authentication-scopes) - * - [Migrate](https://www.figma.com/developers/api#oauth_migration_guide) * * #### Notes * @@ -59,7 +57,7 @@ interface FigmaProfile { * * :::tip * - * The Bitbucket provider comes with a [default configuration](https://github.com/nextauthjs/next-auth/blob/main/packages/core/src/providers/bitbucket.ts). + * The Figma provider comes with a [default configuration](https://github.com/nextauthjs/next-auth/blob/main/packages/core/src/providers/figma.ts). * To override the defaults for your use case, check out [customizing a built-in OAuth provider](https://authjs.dev/guides/configuring-oauth-providers). * * ::: @@ -90,25 +88,7 @@ export default function Figma( state, }, }, - token: { - url: "https://api.figma.com/v1/oauth/token", - async request({ params, provider }: any) { - return await fetch(provider.token.url, { - method: "POST", - headers: { - "Content-Type": "application/x-www-form-urlencoded", - Authorization: `Basic ${Buffer.from( - `${options.clientId}:${options.clientSecret}` - ).toString("base64")}`, - }, - body: new URLSearchParams({ - code: params.code, - grant_type: "authorization_code", - redirect_uri: options.redirectProxyUrl!, - }).toString(), - }).then((response) => response.json()) - }, - }, + token: "https://api.figma.com/v1/oauth/token", userinfo: "https://api.figma.com/v1/me", profile(profile) { return { From c9fd2923405a9ac035ed5661aa59e19ce6d688c0 Mon Sep 17 00:00:00 2001 From: Falco Winkler <8613031+falcowinkler@users.noreply.github.com> Date: Sat, 25 Jan 2025 09:59:36 +0100 Subject: [PATCH 5/5] simplify state generation --- packages/core/src/providers/figma.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/core/src/providers/figma.ts b/packages/core/src/providers/figma.ts index eddd2d2f6e..29afe9b32b 100644 --- a/packages/core/src/providers/figma.ts +++ b/packages/core/src/providers/figma.ts @@ -75,8 +75,6 @@ interface FigmaProfile { export default function Figma( options: OAuthUserConfig ): OAuth2Config { - const bytes = crypto.getRandomValues(new Uint8Array(16)) - const state = Buffer.from(bytes).toString("base64") return { id: "figma", name: "Figma", @@ -85,9 +83,9 @@ export default function Figma( url: "https://www.figma.com/oauth", params: { scope: "files:read", - state, }, }, + checks: ["state"], token: "https://api.figma.com/v1/oauth/token", userinfo: "https://api.figma.com/v1/me", profile(profile) {