Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: discord auth #1249

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion account-kit/react/src/components/auth/sections/OAuth.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { memo } from "react";
import { AppleIcon, FacebookIcon, GoogleIcon } from "../../../icons/oauth.js";
import {
AppleIcon,
FacebookIcon,
GoogleIcon,
DiscordIcon,
} from "../../../icons/auth-icons/index.js";
import { assertNever } from "../../../utils.js";
import { Button } from "../../button.js";
import { useOAuthVerify } from "../hooks/useOAuthVerify.js";
Expand Down Expand Up @@ -31,6 +36,12 @@ export const OAuth = memo(({ ...config }: Props) => {
Apple
</Button>
);
case "discord":
return (
<Button variant="social" icon={<DiscordIcon />} onClick={authenticate}>
Discord
</Button>
);
case "auth0":
return (
<Button
Expand Down
21 changes: 21 additions & 0 deletions account-kit/react/src/icons/auth-icons/apple.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { SVGProps } from "react";

export const AppleIcon = (
props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>
) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width={24}
height={24}
viewBox="0 0 24 24"
fill="none"
{...props}
>
<path
fill="#000"
d="M22.192 18.703c-.363.839-.793 1.61-1.29 2.32-.679.968-1.234 1.637-1.663 2.009-.663.61-1.374.923-2.136.94-.546 0-1.206-.155-1.973-.47-.77-.314-1.477-.47-2.124-.47-.679 0-1.406.156-2.185.47-.78.315-1.407.48-1.888.496-.73.031-1.458-.29-2.184-.966-.464-.404-1.044-1.098-1.739-2.08-.745-1.049-1.358-2.265-1.838-3.652-.514-1.497-.772-2.948-.772-4.352 0-1.608.348-2.995 1.044-4.158A6.122 6.122 0 0 1 5.63 6.58a5.88 5.88 0 0 1 2.955-.835c.58 0 1.34.18 2.285.532.943.354 1.548.533 1.813.533.199 0 .871-.21 2.01-.628 1.079-.388 1.988-.548 2.733-.485 2.02.163 3.536.96 4.545 2.393-1.806 1.094-2.699 2.627-2.681 4.593.016 1.531.572 2.806 1.663 3.817.495.47 1.048.833 1.663 1.09-.134.387-.274.758-.424 1.113ZM17.561.48c0 1.2-.439 2.321-1.313 3.358-1.054 1.234-2.33 1.946-3.714 1.834a3.742 3.742 0 0 1-.027-.455c0-1.152.501-2.386 1.392-3.394.445-.51 1.01-.935 1.696-1.273.685-.334 1.332-.518 1.94-.55.019.16.026.32.026.48Z"
/>
</svg>
);
};
13 changes: 13 additions & 0 deletions account-kit/react/src/icons/auth-icons/discord.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { SVGProps } from "react";

export const DiscordIcon = ({
fill,
...props
}: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>) => (
<svg width="20" height="16" viewBox="0 0 20 16" fill="none" {...props}>
<path
d="M16.9419 1.60281C15.6279 1.00122 14.2407 0.574428 12.8158 0.333344C12.6208 0.681916 12.4443 1.04055 12.2872 1.40775C10.7694 1.17903 9.22584 1.17903 7.70801 1.40775C7.55079 1.04059 7.37437 0.681959 7.17946 0.333344C5.75361 0.576464 4.3655 1.00427 3.05016 1.60595C0.43887 5.4694 -0.269009 9.2369 0.0849305 12.9509C1.61417 14.0808 3.32582 14.9401 5.14548 15.4914C5.55522 14.9403 5.91778 14.3557 6.22933 13.7437C5.63759 13.5227 5.06646 13.2501 4.52255 12.9289C4.6657 12.8251 4.8057 12.7181 4.94098 12.6143C6.52364 13.3586 8.25103 13.7445 9.99996 13.7445C11.7489 13.7445 13.4763 13.3586 15.0589 12.6143C15.1958 12.726 15.3358 12.8329 15.4774 12.9289C14.9324 13.2506 14.3602 13.5238 13.7675 13.7453C14.0786 14.357 14.4412 14.9411 14.8513 15.4914C16.6725 14.9423 18.3855 14.0834 19.915 12.9525C20.3303 8.64542 19.2055 4.91254 16.9419 1.60281ZM6.67765 10.6668C5.69134 10.6668 4.87649 9.77174 4.87649 8.67059C4.87649 7.56945 5.66302 6.66651 6.6745 6.66651C7.68598 6.66651 8.49454 7.56945 8.47724 8.67059C8.45993 9.77174 7.68284 10.6668 6.67765 10.6668ZM13.3223 10.6668C12.3344 10.6668 11.5227 9.77174 11.5227 8.67059C11.5227 7.56945 12.3092 6.66651 13.3223 6.66651C14.3353 6.66651 15.1376 7.56945 15.1203 8.67059C15.103 9.77174 14.3275 10.6668 13.3223 10.6668Z"
fill="#5865F2"
/>
</svg>
);
27 changes: 27 additions & 0 deletions account-kit/react/src/icons/auth-icons/facebook.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { SVGProps } from "react";

export const FacebookIcon = (
props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>
) => {
return (
<svg
width="21"
height="20"
viewBox="0 0 21 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<g>
<path
d="M8.85 19.9C4.1 19.05 0.5 14.95 0.5 10C0.5 4.5 5 0 10.5 0C16 0 20.5 4.5 20.5 10C20.5 14.95 16.9 19.05 12.15 19.9L11.6 19.45H9.4L8.85 19.9Z"
fill="#0062E0"
/>
<path
d="M14.4004 12.7999L14.8504 9.9999H12.2004V8.0499C12.2004 7.2499 12.5004 6.6499 13.7004 6.6499H15.0004V4.0999C14.3004 3.9999 13.5004 3.8999 12.8004 3.8999C10.5004 3.8999 8.90039 5.2999 8.90039 7.7999V9.9999H6.40039V12.7999H8.90039V19.8499C9.45039 19.9499 10.0004 19.9999 10.5504 19.9999C11.1004 19.9999 11.6504 19.9499 12.2004 19.8499V12.7999H14.4004Z"
fill="white"
/>
</g>
</svg>
);
};
39 changes: 39 additions & 0 deletions account-kit/react/src/icons/auth-icons/google.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import type { SVGProps } from "react";

export const GoogleIcon = ({
className,
...props
}: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width={19}
height={20}
fill="none"
{...props}
>
<path
fill="#3E82F1"
fillRule="evenodd"
d="M18.801 10.21c0-.63-.055-1.257-.166-1.876H10v3.546h4.934a4.212 4.212 0 0 1-1.83 2.767v2.3h2.963C17.8 15.351 18.8 13.001 18.8 10.21h.001Z"
clipRule="evenodd"
/>
<path
fill="#32A753"
fillRule="evenodd"
d="M10 19.167c2.475 0 4.55-.821 6.067-2.22l-2.963-2.301c-.82.55-1.87.875-3.104.875-2.388 0-4.409-1.612-5.13-3.78H1.809v2.379A9.167 9.167 0 0 0 10 19.167Z"
clipRule="evenodd"
/>
<path
fill="#F9BB00"
fillRule="evenodd"
d="M4.871 11.742a5.412 5.412 0 0 1 0-3.483V5.884H1.808a9.181 9.181 0 0 0 0 8.234l3.063-2.376Z"
clipRule="evenodd"
/>
<path
fill="#E74133"
d="m1.808 5.884 3.063 2.375c.721-2.167 2.742-3.78 5.13-3.78 1.346 0 2.554.464 3.504 1.371l2.63-2.63C14.546 1.743 12.471.834 10 .834a9.164 9.164 0 0 0-8.192 5.05Z"
/>
</svg>
);
};
6 changes: 6 additions & 0 deletions account-kit/react/src/icons/auth-icons/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { DiscordIcon } from "./discord.js";
import { FacebookIcon } from "./facebook.js";
import { GoogleIcon } from "./google.js";
import { AppleIcon } from "./apple.js";

export { DiscordIcon, GoogleIcon, FacebookIcon, AppleIcon };
93 changes: 5 additions & 88 deletions account-kit/react/src/icons/oauth.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { KnownAuthProvider } from "@account-kit/signer";
import type { SVGProps } from "react";
import { Spinner } from "./spinner.js";
import { GoogleIcon, FacebookIcon, DiscordIcon } from "./auth-icons/index.js";

interface ContinueWithOAuthProps {
provider: KnownAuthProvider;
Expand All @@ -16,7 +16,8 @@ export function ContinueWithOAuth({ provider }: ContinueWithOAuthProps) {
<div className="relative flex flex-col items-center justify-center h-12 w-12">
<Spinner className="absolute top-0 left-0 right-0 bottom-0" />
{(provider === "google" && <GoogleIcon />) ||
(provider === "facebook" && <FacebookIcon />)}
(provider === "facebook" && <FacebookIcon />) ||
(provider === "discord" && <DiscordIcon />)}
</div>
);
}
Expand Down Expand Up @@ -46,92 +47,8 @@ export function OAuthConnectionFailed({
</svg>
</div>
{(provider === "google" && <GoogleIcon />) ||
(provider === "facebook" && <FacebookIcon />)}
(provider === "facebook" && <FacebookIcon />) ||
(provider === "discord" && <DiscordIcon />)}
</div>
);
}

// eslint-disable-next-line jsdoc/require-jsdoc
export const GoogleIcon = ({
className,
...props
}: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width={19}
height={20}
fill="none"
{...props}
>
<path
fill="#3E82F1"
fillRule="evenodd"
d="M18.801 10.21c0-.63-.055-1.257-.166-1.876H10v3.546h4.934a4.212 4.212 0 0 1-1.83 2.767v2.3h2.963C17.8 15.351 18.8 13.001 18.8 10.21h.001Z"
clipRule="evenodd"
/>
<path
fill="#32A753"
fillRule="evenodd"
d="M10 19.167c2.475 0 4.55-.821 6.067-2.22l-2.963-2.301c-.82.55-1.87.875-3.104.875-2.388 0-4.409-1.612-5.13-3.78H1.809v2.379A9.167 9.167 0 0 0 10 19.167Z"
clipRule="evenodd"
/>
<path
fill="#F9BB00"
fillRule="evenodd"
d="M4.871 11.742a5.412 5.412 0 0 1 0-3.483V5.884H1.808a9.181 9.181 0 0 0 0 8.234l3.063-2.376Z"
clipRule="evenodd"
/>
<path
fill="#E74133"
d="m1.808 5.884 3.063 2.375c.721-2.167 2.742-3.78 5.13-3.78 1.346 0 2.554.464 3.504 1.371l2.63-2.63C14.546 1.743 12.471.834 10 .834a9.164 9.164 0 0 0-8.192 5.05Z"
/>
</svg>
);
};

export const FacebookIcon = (
props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>
) => {
return (
<svg
width="21"
height="20"
viewBox="0 0 21 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<g>
<path
d="M8.85 19.9C4.1 19.05 0.5 14.95 0.5 10C0.5 4.5 5 0 10.5 0C16 0 20.5 4.5 20.5 10C20.5 14.95 16.9 19.05 12.15 19.9L11.6 19.45H9.4L8.85 19.9Z"
fill="#0062E0"
/>
<path
d="M14.4004 12.7999L14.8504 9.9999H12.2004V8.0499C12.2004 7.2499 12.5004 6.6499 13.7004 6.6499H15.0004V4.0999C14.3004 3.9999 13.5004 3.8999 12.8004 3.8999C10.5004 3.8999 8.90039 5.2999 8.90039 7.7999V9.9999H6.40039V12.7999H8.90039V19.8499C9.45039 19.9499 10.0004 19.9999 10.5504 19.9999C11.1004 19.9999 11.6504 19.9499 12.2004 19.8499V12.7999H14.4004Z"
fill="white"
/>
</g>
</svg>
);
};

export const AppleIcon = (
props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>
) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width={24}
height={24}
viewBox="0 0 24 24"
fill="none"
{...props}
>
<path
fill="#000"
d="M22.192 18.703c-.363.839-.793 1.61-1.29 2.32-.679.968-1.234 1.637-1.663 2.009-.663.61-1.374.923-2.136.94-.546 0-1.206-.155-1.973-.47-.77-.314-1.477-.47-2.124-.47-.679 0-1.406.156-2.185.47-.78.315-1.407.48-1.888.496-.73.031-1.458-.29-2.184-.966-.464-.404-1.044-1.098-1.739-2.08-.745-1.049-1.358-2.265-1.838-3.652-.514-1.497-.772-2.948-.772-4.352 0-1.608.348-2.995 1.044-4.158A6.122 6.122 0 0 1 5.63 6.58a5.88 5.88 0 0 1 2.955-.835c.58 0 1.34.18 2.285.532.943.354 1.548.533 1.813.533.199 0 .871-.21 2.01-.628 1.079-.388 1.988-.548 2.733-.485 2.02.163 3.536.96 4.545 2.393-1.806 1.094-2.699 2.627-2.681 4.593.016 1.531.572 2.806 1.663 3.817.495.47 1.048.833 1.663 1.09-.134.387-.274.758-.424 1.113ZM17.561.48c0 1.2-.439 2.321-1.313 3.358-1.054 1.234-2.33 1.946-3.714 1.834a3.742 3.742 0 0 1-.027-.455c0-1.152.501-2.386 1.392-3.394.445-.51 1.01-.935 1.696-1.273.685-.334 1.332-.518 1.94-.55.019.16.026.32.026.48Z"
/>
</svg>
);
};
1 change: 1 addition & 0 deletions account-kit/signer/src/oauth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const DEFAULT_SCOPE_AND_CLAIMS: Record<KnownAuthProvider, ScopeAndClaims> = {
apple: { scope: "openid email" },
facebook: { scope: "openid email" },
auth0: { scope: "openid email" },
discord: { scope: "openid email" },
};

/**
Expand Down
7 changes: 6 additions & 1 deletion account-kit/signer/src/signer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,12 @@ export type OauthRedirectConfig =
| { mode: "redirect"; redirectUrl: string }
| { mode: "popup"; redirectUrl?: never };

export type KnownAuthProvider = "google" | "apple" | "facebook" | "auth0";
export type KnownAuthProvider =
| "google"
| "apple"
| "facebook"
| "auth0"
| "discord";

export type OauthMode = "redirect" | "popup";

Expand Down
3 changes: 2 additions & 1 deletion examples/ui-demo/src/app/config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export type Config = {
showPasskey: boolean;
addPasskey: boolean;
showOAuth: boolean;
oAuthMethods: Record<KnownAuthProvider | "auth0", boolean>;
oAuthMethods: Record<KnownAuthProvider | "auth0" | "discord", boolean>;
};
ui: {
theme: "light" | "dark";
Expand Down Expand Up @@ -51,6 +51,7 @@ export const DEFAULT_CONFIG: Config = {
facebook: true,
auth0: false,
apple: false,
discord: true,
// TO DO: extend for BYO auth provider
},
},
Expand Down
10 changes: 9 additions & 1 deletion examples/ui-demo/src/app/sections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,15 @@ export function getSectionsForConfig(
}
if (showOAuth) {
for (const [method, enabled] of Object.entries(oAuthMethods)) {
if (enabled) {
if (method === "discord") {
midSection.push({
type: "social",
authProviderId: "auth0",
mode: "popup",
auth0Connection: "discord",
logoUrl: "/images/discord.svg",
});
} else if (enabled) {
midSection.push({
type: "social",
authProviderId: method as KnownAuthProvider, // TODO: extend for BYO auth provider
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { BiometricIcon } from "../icons/biometric";
import { ExternalLinkIcon } from "../icons/external-link";
import { FacebookIcon } from "../icons/facebook";
import { GoogleIcon } from "../icons/google";
import { DiscordIcon } from "../icons/discord";
import { LockIcon } from "../icons/lock";
import { MailIcon } from "../icons/mail";
import { SocialIcon } from "../icons/social";
Expand Down Expand Up @@ -94,6 +95,22 @@ export const Authentication = ({ className }: { className?: string }) => {
});
};

const setAddDiscordAuth = () => {
setAuth({
oAuthMethods: {
...auth.oAuthMethods,
discord: !auth.oAuthMethods.discord,
},
});
Metrics.trackEvent({
name: "authentication_toggled",
data: {
auth_type: "oauth_discord",
enabled: !auth.oAuthMethods.discord,
},
});
};

return (
<div className={cn("flex flex-col gap-5", className)}>
<div className="flex flex-row gap-2 items-center">
Expand Down Expand Up @@ -125,6 +142,11 @@ export const Authentication = ({ className }: { className?: string }) => {
icon={<FacebookIcon />}
onClick={setAddFacebookAuth}
/>
<OAuthMethod
active={auth.oAuthMethods.discord}
icon={<DiscordIcon />}
onClick={setAddDiscordAuth}
/>
<ExternalLink
href={links.auth0}
onClick={() => {
Expand Down
45 changes: 45 additions & 0 deletions examples/ui-demo/src/components/icons/discord.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { JSX, SVGProps } from "react";

export const DiscordIcon = ({
fill,
...props
}: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>) => (
<svg
width="21"
height="20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<g clip-path="url(#a)">
<path
d="M15.9785 0H5.35352C2.76468 0 .666016 2.09867.666016 4.6875v10.625C.666016 17.9013 2.76468 20 5.35352 20H15.9785c2.5889 0 4.6875-2.0987 4.6875-4.6875V4.6875C20.666 2.09867 18.5674 0 15.9785 0Z"
fill="#5865F2"
/>
<mask
id="b"
maskUnits="userSpaceOnUse"
x="2"
y="3"
width="17"
height="14"
>
<path
d="M2.85352 3.98438H18.4785V16.0883H2.85352V3.98438Z"
fill="#fff"
/>
</mask>
<g mask="url(#b)">
<path
d="M16.0807 5.06249c-1.013-.46502-2.0821-.79662-3.1804-.98649-.01-.00185-.0203-.0005-.0295.00385s-.0167.01147-.0216.02037c-.1374.24422-.2896.56297-.396.81344-1.2011-.17985-2.3958-.17985-3.57215 0-.10657-.2561-.26422-.56922-.40219-.81344-.00511-.00871-.01272-.01568-.02185-.02-.00913-.00433-.01935-.00579-.02932-.00422-1.09843.18949-2.16754.5211-3.18039.98649-.00867.00368-.01599.00995-.02094.01796C3.20073 8.1067 2.64589 11.0586 2.91808 13.9739c.00075.0071.00294.0141.00643.0203.00349.0063.00821.0118.01388.0163 1.33641.9814 2.63102 1.5773 3.90156 1.9722.00989.003.02043.0028.03024-.0004.0098-.0032.01838-.0093.02461-.0175.30054-.4105.56843-.8433.7982-1.2983.00316-.0063.00497-.0131.0053-.0201.00033-.007-.00082-.0139-.00339-.0204-.00256-.0065-.00647-.0124-.01147-.0173-.00501-.0049-.01099-.0087-.01755-.0111-.425-.1612-.82961-.3577-1.21883-.5809-.00709-.0042-.01304-.01-.01733-.017-.00429-.0071-.00679-.015-.00728-.0232-.00049-.0083.00106-.0165.00449-.0239.00343-.0075.00865-.014.0152-.019.08211-.0614.1628-.1246.24203-.1897.00694-.0057.01534-.0094.02425-.0106.00892-.0013.018 0 .02622.0037 2.55719 1.1675 5.32556 1.1675 7.85246 0 .0083-.0039.0175-.0054.0265-.0043.0091.0011.0176.0048.0247.0106.0793.0654.1602.1289.2427.1903.0065.0049.0118.0114.0153.0188.0035.0075.0051.0157.0047.0239-.0005.0082-.0029.0162-.0071.0232-.0043.0071-.0102.013-.0172.0172-.3895.2274-.7974.4215-1.2195.5803-.0065.0025-.0125.0064-.0174.0113-.005.005-.0089.011-.0114.0175-.0025.0066-.0036.0136-.0032.0206.0004.007.0023.0138.0055.0201.2338.4514.5003.8852.7975 1.2976.0061.0085.0146.0148.0245.0181.0098.0034.0204.0035.0304.0005 1.2767-.3949 2.5713-.9908 3.9078-1.9722.0057-.0043.0105-.0096.014-.0158.0035-.0062.0056-.0131.0063-.0202.3258-3.3704-.5457-6.29811-2.3102-8.89342-.0044-.00843-.0116-.01503-.0203-.01859ZM8.07487 12.1988c-.76992 0-1.40429-.7068-1.40429-1.5748 0-.86808.62211-1.57487 1.40429-1.57487.78828 0 1.41649.71304 1.40414 1.57487 0 .868-.62195 1.5748-1.40414 1.5748Zm5.19183 0c-.7699 0-1.4042-.7068-1.4042-1.5748 0-.86808.6221-1.57487 1.4042-1.57487.7883 0 1.4165.71304 1.4043 1.57487 0 .868-.616 1.5748-1.4043 1.5748Z"
fill="#fff"
/>
</g>
</g>
<defs>
<clipPath id="a">
<path fill="#fff" transform="translate(.666016)" d="M0 0h20v20H0z" />
</clipPath>
</defs>
</svg>
);
Loading
Loading