Skip to content

Commit

Permalink
a rough implementation of the issue solution
Browse files Browse the repository at this point in the history
  • Loading branch information
Dprof-in-tech committed Aug 4, 2024
1 parent 10de6b3 commit 7d625e8
Show file tree
Hide file tree
Showing 11 changed files with 10,119 additions and 2,451 deletions.
Empty file added .env.example
Empty file.
18 changes: 18 additions & 0 deletions next-auth.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import NextAuth from "next-auth"

declare module "next-auth" {
interface Session {
user: {
name?: string | null
email?: string | null
image?: string | null
publicKey?: string
secretKey?: string
}
}

interface User {
publicKey?: string
secretKey?: string
}
}
12,139 changes: 9,718 additions & 2,421 deletions package-lock.json

Large diffs are not rendered by default.

11 changes: 10 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,28 @@
"preinstall": "npm run build:contracts && npm run bindings"
},
"dependencies": {
"@next-auth/firebase-adapter": "^2.0.1",
"@radix-ui/react-dialog": "1.1.1",
"@stellar/freighter-api": "^2.0.0",
"@stellar/stellar-sdk": "12.1.0",
"@stellar/wallet-sdk": "^0.11.2",
"@sveltejs/kit": "^2.5.20",
"abundance-token": "file:./.soroban-example-dapp/abundance-token",
"crowdfund-contract": "file:./.soroban-example-dapp/crowdfund-contract",
"crypto-js": "^4.2.0",
"humanize-duration": "^3.32.1",
"moment": "^2.30.1",
"next": "^14.2.4",
"next-auth": "^4.24.7",
"react": "^18.3.1",
"react-dom": "^18.3.1"
"react-dom": "^18.3.1",
"react-icons": "^5.2.1",
"svelte-local-storage-store": "^0.6.4"
},
"devDependencies": {
"@types/crypto-js": "^4.2.2",
"@types/humanize-duration": "^3.27.4",
"@types/next-auth": "^3.15.0",
"@types/node": "20.14.9",
"@types/react": "18.3.3",
"@types/react-dom": "18.3.0",
Expand Down
19 changes: 12 additions & 7 deletions pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import type { AppProps } from 'next/app'
import { SessionProvider } from 'next-auth/react'
import '../styles/globals.css'
import type { AppProps } from 'next/app'
import NextComponentType from 'next/app';


function MyApp({ Component, pageProps }: AppProps) {
export default function App({
Component,
pageProps: { session, ...pageProps },
}: AppProps & { Component: NextComponentType }) {
return (
<Component {...pageProps} />
);
<SessionProvider session={session}>
{' '}
<Component {...pageProps} />{' '}
</SessionProvider>
)
}

export default MyApp
48 changes: 48 additions & 0 deletions pages/api/auth/[...nextauth].ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import NextAuth, { AuthOptions } from "next-auth"
import GoogleProvider from "next-auth/providers/google"
import TwitterProvider from "next-auth/providers/twitter"
import GithubProvider from "next-auth/providers/github"
import { Keypair } from "@stellar/stellar-sdk"

export const authOptions: AuthOptions = {
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID ?? '',
clientSecret: process.env.GOOGLE_CLIENT_SECRET ?? '',
}),
TwitterProvider({
clientId: process.env.TWITTER_CLIENT_ID ?? '',
clientSecret: process.env.TWITTER_CLIENT_SECRET ?? '',
version: "2.0",
}),
GithubProvider({
clientId: process.env.GITHUB_CLIENT_ID ?? '',
clientSecret: process.env.GITHUB_CLIENT_SECRET ?? '',
}),
],
callbacks: {
async signIn({ user }: { user: any }) {
// Generate Keypair
const keypair = Keypair.random()
user.publicKey = keypair.publicKey()
user.secretKey = keypair.secret()

return true
},
async jwt({ token, user }: { token: any, user?: any }) {
if (user) {
token.publicKey = user.publicKey
token.secretKey = user.secretKey
}
return token
},
async session({ session, token }: { session: any, token: any }) {
session.user.publicKey = token.publicKey
session.user.secretKey = token.secretKey
return session
}
},
session: {},
}

export default NextAuth(authOptions)
19 changes: 19 additions & 0 deletions pages/api/restricted.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { getServerSession } from "next-auth/next"
import { authOptions } from "./auth/[...nextauth]"

const handler = async (req: any, res: any) => {
const session = await getServerSession(req, res, authOptions)

if (session) {
res.send({
content:
"This is protected content. You can access this content because you are signed in.",
})
} else {
res.send({
error: "You must be signed in to view the protected content on this page.",
})
}
}

export default handler;
113 changes: 113 additions & 0 deletions pages/home.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import React, { useEffect, useState } from 'react'
import type { NextPage } from 'next'
import Head from 'next/head'
import styles from '../styles/Home.module.css'
import { Campaign, Pledge } from '../components/organisms'
import { WalletData } from '../components/molecules'
import { useSession, signIn, signOut } from 'next-auth/react'
import { useRouter } from 'next/router'
import * as StellarSdk from '@stellar/stellar-sdk'
import CryptoJS from 'crypto-js'

const Home: NextPage = () => {
const { data: session, status } = useSession()
const router = useRouter()
const [publicKey, setPublicKey] = useState<string | null>(null)
const [secretKey, setSecretKey] = useState<string | null>(null)
const [pincode, setPincode] = useState<string>('')
const [isKeyPairGenerated, setIsKeyPairGenerated] = useState<boolean>(false)

useEffect(() => {
if (status !== 'loading' && !session) {
router.push('/')
}
}, [session, status, router])

useEffect(() => {
if (status !== 'loading' && session) {
const encryptedSecretKey = localStorage.getItem('encryptedSecretKey')
if (encryptedSecretKey) {
setIsKeyPairGenerated(true)
} else {
generateKeyPair()
}
}
}, [session, status])

const generateKeyPair = () => {
const pair = StellarSdk.Keypair.random()
setPublicKey(pair.publicKey())
setSecretKey(pair.secret())
}

const encryptSecretKey = (key: string, pincode: string) => {
return CryptoJS.AES.encrypt(key, pincode).toString()
}

const handlePincodeSubmit = () => {
if (secretKey) {
const encryptedSecretKey = encryptSecretKey(secretKey, pincode)
localStorage.setItem('encryptedSecretKey', encryptedSecretKey)
alert('Key pair generated and secret key encrypted and stored locally.')
setIsKeyPairGenerated(true)
}
}

if (status === 'loading') {
return <div>Loading...</div>
}

return (
<>
<Head>
<title>
Crowdfund Template - An example of how to run a crowdfund campaign on
Soroban.
</title>
<meta
name="description"
content="An example of loading information from a stellar smart contract"
/>
<link rel="icon" href="/favicon.ico" />
</Head>

<header className={styles.header}>
<h3>Starfund</h3>
{session ? (
<>
Signed in as {session.user?.email || session.user?.name} <br />
<button onClick={() => signOut()}>Sign Out</button>
</>
) : (
<div>Not signed in</div>
)}
<WalletData />
</header>
<main className={styles.main}>
{session && !isKeyPairGenerated && publicKey && secretKey ? (
<div className={styles.keyPair}>
<h3>Your Key Pair</h3>
<p>Public Key: {publicKey}</p>
<p>Secret Key: {secretKey}</p>
<div>
<input
type="password"
placeholder="Enter pincode to encrypt your secret key"
value={pincode}
onChange={(e) => setPincode(e.target.value)}
/>
<button onClick={handlePincodeSubmit}>Submit Pincode</button>
</div>
</div>
) : (
<div className={styles.content}>
<Campaign />
<Pledge />
</div>
)}
</main>
</>
)
}

export default Home
82 changes: 60 additions & 22 deletions pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,75 @@
import React from 'react'
import React, { useEffect, useState } from 'react'
import type { NextPage } from 'next'
import Head from 'next/head'
import styles from '../styles/Home.module.css'
import { Campaign, Pledge } from '../components/organisms'
import { WalletData } from '../components/molecules'
import { useSession, signIn } from 'next-auth/react'
import { useRouter } from 'next/router'
import { FaGoogle, FaTwitter, FaGithub } from 'react-icons/fa'
import * as StellarSdk from '@stellar/stellar-sdk'
import CryptoJS from 'crypto-js'

const Index: NextPage = () => {
const { data: session, status } = useSession()
const router = useRouter()
const [publicKey, setPublicKey] = useState<string | null>(null)
const [secretKey, setSecretKey] = useState<string | null>(null)
const [pincode, setPincode] = useState<string>('')

useEffect(() => {
if (status !== 'loading' && session) {
generateKeyPair()
}
}, [session, status])

const generateKeyPair = () => {
const pair = StellarSdk.Keypair.random()
setPublicKey(pair.publicKey())
setSecretKey(pair.secret())
}

const encryptSecretKey = (key: string, pincode: string) => {
return CryptoJS.AES.encrypt(key, pincode).toString()
}

const handlePincodeSubmit = () => {
if (secretKey) {
const encryptedSecretKey = encryptSecretKey(secretKey, pincode)
localStorage.setItem('encryptedSecretKey', encryptedSecretKey)
alert('Key pair generated and secret key encrypted and stored locally.')
router.push('/home')
}
}

const Home: NextPage = () => {
return (
<>
<Head>
<title>
Crowdfund Template - An example of how to run a crowdfund campaign on
Soroban.
</title>
<meta
name="description"
content="An example of loading information from a stellar smart contract"
/>
<link rel="icon" href="/favicon.ico" />
<title>Soroban Social Login</title>
</Head>

<header className={styles.header}>
<h3>Starfund</h3>
<WalletData />
</header>
<main className={styles.main}>
<div className={styles.content}>
<Campaign />
<Pledge />
<div className={styles.login}>
<button onClick={() => signIn('google')}><FaGoogle /> Sign in with Google</button>
<button onClick={() => signIn('twitter')}><FaTwitter /> Sign in with Twitter</button>
<button onClick={() => signIn('github')}><FaGithub /> Sign in with GitHub</button>
</div>
{publicKey && secretKey && (
<div className={styles.keyPair}>
<h3>Your Key Pair</h3>
<p>Public Key: {publicKey}</p>
<p>Secret Key: {secretKey}</p>
<div>
<input
type="password"
placeholder="Enter pincode to encrypt your secret key"
value={pincode}
onChange={(e) => setPincode(e.target.value)}
/>
<button onClick={handlePincodeSubmit}>Submit Pincode</button>
</div>
</div>
)}
</main>
</>
)
}

export default Home
export default Index
Loading

0 comments on commit 7d625e8

Please sign in to comment.