From 0d13d2c689ac6517f28ef958db26c5a5e9a6de1b Mon Sep 17 00:00:00 2001 From: Marc-Aurele Besner <82244926+marc-aurele-besner@users.noreply.github.com> Date: Fri, 3 May 2024 14:50:35 -0400 Subject: [PATCH 1/5] Add github session and jwt types --- explorer/next-auth.d.ts | 4 ++++ explorer/src/constants/session.ts | 7 ++++++- explorer/src/types/jwt.ts | 5 +++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/explorer/next-auth.d.ts b/explorer/next-auth.d.ts index 8c39a5cbc..d78b33f76 100644 --- a/explorer/next-auth.d.ts +++ b/explorer/next-auth.d.ts @@ -10,6 +10,7 @@ declare module 'next-auth' { DIDs: string[] subspace?: SubspaceToken discord?: DiscordToken + github?: GitHubToken } export interface Session { @@ -25,6 +26,7 @@ declare module 'next-auth/client' { DIDs: string[] subspace?: SubspaceToken discord?: DiscordToken + github?: GitHubToken } export interface Session { @@ -40,6 +42,7 @@ declare module 'next-auth/jwt' { DIDs: string[] subspace?: SubspaceToken discord?: DiscordToken + github?: GitHubToken } interface JWT { @@ -47,5 +50,6 @@ declare module 'next-auth/jwt' { DIDs: string[] subspace?: SubspaceToken discord?: DiscordToken + github?: GitHubToken } } diff --git a/explorer/src/constants/session.ts b/explorer/src/constants/session.ts index f5f6d9223..ebaa992d4 100644 --- a/explorer/src/constants/session.ts +++ b/explorer/src/constants/session.ts @@ -1,4 +1,4 @@ -import type { DiscordToken, SubspaceToken } from 'types/jwt' +import type { DiscordToken, GitHubToken, SubspaceToken } from 'types/jwt' export const TOKEN_EXPIRATION = 60 * 60 * 24 // 1 day @@ -25,3 +25,8 @@ export const DEFAULT_DISCORD_TOKEN: DiscordToken = { }, }, } + +export const DEFAULT_GITHUB_TOKEN: GitHubToken = { + id: '', + username: '', +} diff --git a/explorer/src/types/jwt.ts b/explorer/src/types/jwt.ts index f2d7cbc20..5fadaacf1 100644 --- a/explorer/src/types/jwt.ts +++ b/explorer/src/types/jwt.ts @@ -21,3 +21,8 @@ export type DiscordToken = { } } } + +export type GitHubToken = { + id: string + username: string +} From 9f5e7c03ee9639426c01ecd3e47e6c1230e787c9 Mon Sep 17 00:00:00 2001 From: Marc-Aurele Besner <82244926+marc-aurele-besner@users.noreply.github.com> Date: Fri, 3 May 2024 14:50:52 -0400 Subject: [PATCH 2/5] add github openid connector --- explorer/src/utils/auth/providers/github.ts | 46 +++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 explorer/src/utils/auth/providers/github.ts diff --git a/explorer/src/utils/auth/providers/github.ts b/explorer/src/utils/auth/providers/github.ts new file mode 100644 index 000000000..7416e7d84 --- /dev/null +++ b/explorer/src/utils/auth/providers/github.ts @@ -0,0 +1,46 @@ +import * as jsonwebtoken from 'jsonwebtoken' +import type { TokenSet } from 'next-auth' +import { JWT } from 'next-auth/jwt' +import GitHubProvider, { GithubProfile } from 'next-auth/providers/github' +import { cookies } from 'next/headers' + +const { GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET } = process.env + +export const GitHub = () => { + return GitHubProvider({ + // client credentials + clientId: GITHUB_CLIENT_ID || '', + clientSecret: GITHUB_CLIENT_SECRET || '', + + // fetch discord profile + profile: async (profile: GithubProfile, token: TokenSet) => { + try { + if (!token.access_token) throw new Error('No access token') + + if (!process.env.NEXTAUTH_SECRET) throw new Error('No secret') + const { NEXTAUTH_SECRET } = process.env + + const { get } = cookies() + const sessionToken = get('next-auth.session-token')?.value || '' + const session = jsonwebtoken.verify(sessionToken, NEXTAUTH_SECRET, { + algorithms: ['HS256'], + }) as JWT + const did = 'did:openid:github:' + profile.id + + return { + id: session.id || did, + DIDs: [...session.DIDs, did], + subspace: session.subspace, + discord: session.discord, + github: { + id: profile.id, + username: profile.login, + }, + } + } catch (error) { + console.error('Error fetching Discord profile:', error) + throw new Error('Failed to fetch Discord profile') + } + }, + }) +} From 1d743dac9dbbece954e9fd93beb3f4c7ddc74012 Mon Sep 17 00:00:00 2001 From: Marc-Aurele Besner <82244926+marc-aurele-besner@users.noreply.github.com> Date: Fri, 3 May 2024 14:51:05 -0400 Subject: [PATCH 3/5] add to providers list --- explorer/src/utils/auth/authOptions.ts | 1 + explorer/src/utils/auth/providers/index.ts | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/explorer/src/utils/auth/authOptions.ts b/explorer/src/utils/auth/authOptions.ts index d72cbef99..ddbbc6e34 100644 --- a/explorer/src/utils/auth/authOptions.ts +++ b/explorer/src/utils/auth/authOptions.ts @@ -25,6 +25,7 @@ export const authOptions: AuthOptions = { token.DIDs = user.DIDs token.subspace = user.subspace token.discord = user.discord + token.github = user.github } return token }, diff --git a/explorer/src/utils/auth/providers/index.ts b/explorer/src/utils/auth/providers/index.ts index 5a7410ca0..17c7a07e5 100644 --- a/explorer/src/utils/auth/providers/index.ts +++ b/explorer/src/utils/auth/providers/index.ts @@ -1,6 +1,7 @@ import { Provider } from 'next-auth/providers' import { Discord } from './discord' +import { GitHub } from './github' import { Nova } from './nova' import { Subspace } from './subspace' -export const providers: Provider[] = [Discord(), Subspace(), Nova()] +export const providers: Provider[] = [Discord(), GitHub(), Subspace(), Nova()] From 67bbc15aef9df7631d6497c5715a7a2589781bab Mon Sep 17 00:00:00 2001 From: Marc-Aurele Besner <82244926+marc-aurele-besner@users.noreply.github.com> Date: Fri, 3 May 2024 14:51:24 -0400 Subject: [PATCH 4/5] keep github in jwt when connecting to other oauth --- explorer/src/utils/auth/providers/discord.ts | 2 ++ explorer/src/utils/auth/providers/subspace.ts | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/explorer/src/utils/auth/providers/discord.ts b/explorer/src/utils/auth/providers/discord.ts index 663e4d8b2..2596e78e7 100644 --- a/explorer/src/utils/auth/providers/discord.ts +++ b/explorer/src/utils/auth/providers/discord.ts @@ -1,3 +1,4 @@ +import { DEFAULT_GITHUB_TOKEN } from 'constants/session' import * as jsonwebtoken from 'jsonwebtoken' import type { TokenSet } from 'next-auth' import { JWT } from 'next-auth/jwt' @@ -83,6 +84,7 @@ export const Discord = () => { }, }, }, + github: session.github || DEFAULT_GITHUB_TOKEN, } } catch (error) { console.error('Error fetching Discord profile:', error) diff --git a/explorer/src/utils/auth/providers/subspace.ts b/explorer/src/utils/auth/providers/subspace.ts index 4322c3e81..d858c8bfd 100644 --- a/explorer/src/utils/auth/providers/subspace.ts +++ b/explorer/src/utils/auth/providers/subspace.ts @@ -1,5 +1,5 @@ import { cryptoWaitReady, signatureVerify } from '@polkadot/util-crypto' -import { DEFAULT_DISCORD_TOKEN } from 'constants/session' +import { DEFAULT_DISCORD_TOKEN, DEFAULT_GITHUB_TOKEN } from 'constants/session' import type { Provider } from 'next-auth/providers' import CredentialsProvider from 'next-auth/providers/credentials' import { verifySubspaceAccountRoles } from '../vcs/subspace' @@ -51,6 +51,7 @@ export const Subspace = () => { }, }, discord: DEFAULT_DISCORD_TOKEN, + github: DEFAULT_GITHUB_TOKEN, } } catch (error) { console.error('Error verify Subspace wallet ownership:', error) From 8babcd92776eccf6c355bab38802d37a9b2490eb Mon Sep 17 00:00:00 2001 From: Marc-Aurele Besner <82244926+marc-aurele-besner@users.noreply.github.com> Date: Fri, 3 May 2024 14:51:36 -0400 Subject: [PATCH 5/5] add to wallet sidekick --- .../WalletSideKick/GetDiscordRoles.tsx | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/explorer/src/components/WalletSideKick/GetDiscordRoles.tsx b/explorer/src/components/WalletSideKick/GetDiscordRoles.tsx index 4a153edbe..644505057 100644 --- a/explorer/src/components/WalletSideKick/GetDiscordRoles.tsx +++ b/explorer/src/components/WalletSideKick/GetDiscordRoles.tsx @@ -101,6 +101,32 @@ export const DiscordFlow: FC = () => { ) } +export const GitHubFlow: FC = () => { + const { data: session } = useSession() + + const handleConnectGitHub = useCallback( + async () => await signIn('github', { redirect: false }), + [], + ) + + return ( + session?.user?.subspace && ( + + {session?.user?.discord?.vcs.member ? ( + <> + + + Refresh + + + ) : ( + Connect + )} + + ) + ) +} + export const GetDiscordRoles: FC = ({ subspaceAccount }) => { const { data: session } = useSession() @@ -128,6 +154,7 @@ export const GetDiscordRoles: FC = ({ subspaceAccount }) => )} + @@ -144,6 +171,7 @@ export const GetDiscordRoles: FC = ({ subspaceAccount }) => )} +