diff --git a/apps/backend/prisma/migrations/20240919223009_x_and_slack_oauth/migration.sql b/apps/backend/prisma/migrations/20240919223009_x_and_slack_oauth/migration.sql index 6c2cbd33e..b1c92393b 100644 --- a/apps/backend/prisma/migrations/20240919223009_x_and_slack_oauth/migration.sql +++ b/apps/backend/prisma/migrations/20240919223009_x_and_slack_oauth/migration.sql @@ -7,4 +7,3 @@ ALTER TYPE "StandardOAuthProviderType" ADD VALUE 'X'; -ALTER TYPE "StandardOAuthProviderType" ADD VALUE 'SLACK'; diff --git a/apps/backend/prisma/schema.prisma b/apps/backend/prisma/schema.prisma index f3e67de98..f54c42f68 100644 --- a/apps/backend/prisma/schema.prisma +++ b/apps/backend/prisma/schema.prisma @@ -569,7 +569,6 @@ enum StandardOAuthProviderType { LINKEDIN APPLE X - SLACK } model OAuthToken { diff --git a/apps/backend/src/oauth/index.tsx b/apps/backend/src/oauth/index.tsx index 7922fb9ff..919675b97 100644 --- a/apps/backend/src/oauth/index.tsx +++ b/apps/backend/src/oauth/index.tsx @@ -14,7 +14,6 @@ import { GoogleProvider } from "./providers/google"; import { LinkedInProvider } from "./providers/linkedin"; import { MicrosoftProvider } from "./providers/microsoft"; import { MockProvider } from "./providers/mock"; -import { SlackProvider } from "./providers/slack"; import { SpotifyProvider } from "./providers/spotify"; import { XProvider } from "./providers/x"; @@ -30,7 +29,6 @@ const _providers = { bitbucket: BitbucketProvider, linkedin: LinkedInProvider, x: XProvider, - slack: SlackProvider, } as const; const mockProvider = MockProvider; diff --git a/apps/backend/src/oauth/providers/slack.tsx b/apps/backend/src/oauth/providers/slack.tsx deleted file mode 100644 index 0b986ee43..000000000 --- a/apps/backend/src/oauth/providers/slack.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import { OAuthBaseProvider, TokenSet } from "./base"; -import { OAuthUserInfo, validateUserInfo } from "../utils"; -import { getEnvVariable } from "@stackframe/stack-shared/dist/utils/env"; - -export class SlackProvider extends OAuthBaseProvider { - private constructor( - ...args: ConstructorParameters - ) { - super(...args); - } - - static async create(options: { clientId: string, clientSecret: string }) { - return new SlackProvider( - ...(await OAuthBaseProvider.createConstructorArgs({ - issuer: "https://slack.com", - authorizationEndpoint: "https://slack.com/oauth/v2/authorize", - tokenEndpoint: "https://slack.com/api/oauth.v2.access", - redirectUri: - getEnvVariable("STACK_BASE_URL") + - "/api/v1/auth/oauth/callback/slack", - baseScope: "", - authorizationExtraParams: { - user_scope: "email,profile,openid", - }, - ...options, - })) - ); - } - - async postProcessUserInfo(tokenSet: TokenSet): Promise { - const userInfo = await fetch( - "https://slack.com/api/openid.connect.userInfo", { - headers: { - Authorization: `Bearer ${tokenSet.accessToken}`, - } - } - ).then(res => res.json()); - return validateUserInfo({ - accountId: userInfo.sub?.toString(), - displayName: userInfo.name, - email: userInfo.email, - profileImageUrl: userInfo.picture, - emailVerified: userInfo.email_verified, - }); - } -} \ No newline at end of file diff --git a/apps/backend/src/oauth/providers/x.tsx b/apps/backend/src/oauth/providers/x.tsx index 6a7936d34..453a0e03f 100644 --- a/apps/backend/src/oauth/providers/x.tsx +++ b/apps/backend/src/oauth/providers/x.tsx @@ -32,12 +32,14 @@ export class XProvider extends OAuthBaseProvider { } ).then((res) => res.json()); + console.log("userInfo", userInfo); + return validateUserInfo({ accountId: userInfo?.id?.toString(), displayName: userInfo.name || userInfo.username, - // email: undefined, // There is no way of getting email from X Oauth2.0 API + email: null, // There is no way of getting email from X Oauth2.0 API profileImageUrl: userInfo.profile_image_url as any, emailVerified: false, - }); + }, { expectNoEmail: true }); } } \ No newline at end of file diff --git a/apps/backend/src/oauth/utils.tsx b/apps/backend/src/oauth/utils.tsx index 50f9d6f5e..b0ac14ed8 100644 --- a/apps/backend/src/oauth/utils.tsx +++ b/apps/backend/src/oauth/utils.tsx @@ -6,11 +6,17 @@ export type OAuthUserInfo = yup.InferType; const OAuthUserInfoSchema = yupObject({ accountId: yupString().min(1).required(), displayName: yupString().nullable().default(null), - email: yupString().email().required(), + email: yupString().email().nullable().default(null), profileImageUrl: yupString().nullable().default(null), emailVerified: yupBoolean().default(false), }); -export function validateUserInfo(userInfo: Partial>): OAuthUserInfo { +export function validateUserInfo( + userInfo: Partial>, + options?: { expectNoEmail?: boolean } +): OAuthUserInfo { + if (!options?.expectNoEmail && !userInfo.email) { + throw new Error("Email is required"); + } return OAuthUserInfoSchema.validateSync(userInfo); } \ No newline at end of file diff --git a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx index 49fe458aa..c8e059aa4 100644 --- a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx +++ b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx @@ -28,7 +28,6 @@ function toTitle(id: string) { bitbucket: "Bitbucket", linkedin: "LinkedIn", x: "X", - slack: "Slack", }[id]; } diff --git a/apps/oauth-mock-server/src/index.ts b/apps/oauth-mock-server/src/index.ts index 3ac8fa03a..594910531 100644 --- a/apps/oauth-mock-server/src/index.ts +++ b/apps/oauth-mock-server/src/index.ts @@ -12,7 +12,6 @@ const mockedProviders = [ "gitlab", "bitbucket", "x", - "slack", ]; const configuration: Configuration = { diff --git a/docs/fern/docs/pages/getting-started/production.mdx b/docs/fern/docs/pages/getting-started/production.mdx index a24cf1a00..97ad284cc 100644 --- a/docs/fern/docs/pages/getting-started/production.mdx +++ b/docs/fern/docs/pages/getting-started/production.mdx @@ -68,11 +68,6 @@ To use your own OAuth provider setups in production, follow these steps for each Callback URL: `https://api.stack-auth.com/api/v1/auth/oauth/callback/x` - - [X OAuth Setup Guide](https://api.slack.com/authentication/oauth-v2) - Callback URL: - `https://api.stack-auth.com/api/v1/auth/oauth/callback/slack` - 2. **Enter OAuth Credentials**: Go to the `Auth Methods` section in the Stack dashboard, open the provider's settings, switch from shared keys to custom keys, and enter the client ID and client secret. diff --git a/packages/stack-shared/src/utils/oauth.tsx b/packages/stack-shared/src/utils/oauth.tsx index 24b9f925c..df422db93 100644 --- a/packages/stack-shared/src/utils/oauth.tsx +++ b/packages/stack-shared/src/utils/oauth.tsx @@ -1,4 +1,4 @@ -export const standardProviders = ["google", "github", "microsoft", "spotify", "facebook", "discord", "gitlab", "bitbucket", "linkedin", "apple", "x", "slack"] as const; +export const standardProviders = ["google", "github", "microsoft", "spotify", "facebook", "discord", "gitlab", "bitbucket", "linkedin", "apple", "x"] as const; // No more shared providers should be added except for special cases export const sharedProviders = ["google", "github", "microsoft", "spotify"] as const; export const allProviders = standardProviders; diff --git a/packages/stack/src/components/oauth-button.tsx b/packages/stack/src/components/oauth-button.tsx index 491cfdc14..29351ecc5 100644 --- a/packages/stack/src/components/oauth-button.tsx +++ b/packages/stack/src/components/oauth-button.tsx @@ -148,31 +148,6 @@ function XIcon({ iconSize } : { iconSize: number} ) { ); } -function SlackIcon({ iconSize } : { iconSize: number} ) { - return ( - - - - - - - - - ); -} - const changeColor = (c: Color, value: number) => { if (c.isLight()) { value = -value; @@ -303,15 +278,6 @@ export function OAuthButton({ }; break; } - case 'slack': { - style = { - backgroundColor: "#611f69", - textColor: "#fff", - name: "Slack", - icon: , - }; - break; - } default: { style = { name: provider,