Skip to content
Snippets Groups Projects
Commit eb6356dc authored by Niklas P's avatar Niklas P
Browse files

add env

parent 65ce3153
No related branches found
No related tags found
No related merge requests found
NEXTAUTH_SECRET=YOUR_SECRET_HERE
NEXTAUTH_URL=http://localhost:3000
\ No newline at end of file
...@@ -6,6 +6,8 @@ A tutorial that explains how it works will be published soon on [polkadot.study] ...@@ -6,6 +6,8 @@ A tutorial that explains how it works will be published soon on [polkadot.study]
## Run the Project Locally ## Run the Project Locally
First copy the .env.local.example to .env.local
First, run the development server: First, run the development server:
```bash ```bash
......
...@@ -16,7 +16,7 @@ export const accountValueTemplate = (option: any, props: any) => { ...@@ -16,7 +16,7 @@ export const accountValueTemplate = (option: any, props: any) => {
size={32} size={32}
theme='polkadot' theme='polkadot'
/> />
{option?.meta.name } {option?.name }
</div> </div>
</div> </div>
); );
...@@ -41,8 +41,8 @@ export const accountOptionTemplate = (option: any) => { ...@@ -41,8 +41,8 @@ export const accountOptionTemplate = (option: any) => {
}; };
export default function AccountSelector( ) { export default function AccountSelector( ) {
const { accounts, actingAccountIdx, setActingAccountIdx, setActingAccountByAddress } = useContext(PolkadotExtensionContext) const { accounts, actingAccountIdx, setActingAccountByAddress } = useContext(PolkadotExtensionContext)
// const actingAccount = accounts[actingAccountIdx] const actingAccount = actingAccountIdx !== undefined ? accounts?.[actingAccountIdx] : undefined
return ( return (
<Dropdown <Dropdown
...@@ -50,7 +50,7 @@ export default function AccountSelector( ) { ...@@ -50,7 +50,7 @@ export default function AccountSelector( ) {
optionLabel="address" optionLabel="address"
placeholder="Select Account" placeholder="Select Account"
className={ styles.dropdown } className={ styles.dropdown }
value={ undefined } value={ actingAccount }
itemTemplate={ accountOptionTemplate } itemTemplate={ accountOptionTemplate }
valueTemplate={ accountValueTemplate } valueTemplate={ accountValueTemplate }
onChange={(event) => { onChange={(event) => {
......
...@@ -22,17 +22,14 @@ export default function LoginButton() { ...@@ -22,17 +22,14 @@ export default function LoginButton() {
const injector = actingAccount && actingAccount?.wallet const injector = actingAccount && actingAccount?.wallet
const handleLogin = async () => { const handleLogin = async () => {
if ( ! actingAccount === false ) {
return
}
try { try {
setIsLoading( true ) setIsLoading( true )
let signature = '' let signature = ''
const message = { const message = {
// domain: window.location.host, domain: window.location.host,
address: actingAccount?.address, address: actingAccount?.address,
statement: 'Sign in with polkadot extension to the example tokengated example dApp', statement: 'Sign in with polkadot extension to the example tokengated example dApp',
// uri: window.location.origin, uri: window.location.origin,
version: '1', version: '1',
nonce: await getCsrfToken(), nonce: await getCsrfToken(),
} }
...@@ -44,6 +41,7 @@ export default function LoginButton() { ...@@ -44,6 +41,7 @@ export default function LoginButton() {
// we can use it to sign our message // we can use it to sign our message
const data = await signRaw({ const data = await signRaw({
address: actingAccount.address, address: actingAccount.address,
domain: message.domain,
data: JSON.stringify(message), data: JSON.stringify(message),
type: "bytes" type: "bytes"
}); });
...@@ -71,7 +69,6 @@ export default function LoginButton() { ...@@ -71,7 +69,6 @@ export default function LoginButton() {
} catch (error) { } catch (error) {
setError( 'Cancelled Signature' ) setError( 'Cancelled Signature' )
console.log( error )
setIsLoading( false ) setIsLoading( false )
} }
} }
......
...@@ -25,6 +25,8 @@ export const PolkadotExtensionProvider = ( { children } : { children : ReactNode ...@@ -25,6 +25,8 @@ export const PolkadotExtensionProvider = ( { children } : { children : ReactNode
const setActingAccountByAddress = (address: string) => { const setActingAccountByAddress = (address: string) => {
setActingAccountIdx( accounts?.findIndex( account => account.address === address ) ) setActingAccountIdx( accounts?.findIndex( account => account.address === address ) )
console.log( 'new acting account idx', actingAccountIdx )
} }
const Accounts = async () => { const Accounts = async () => {
......
import { useEffect, useState } from "react";
import type { InjectedAccountWithMeta, InjectedExtension } from "@polkadot/extension-inject/types";
export function usePolkadotExtension() {
const [accounts, setAccounts] = useState<InjectedAccountWithMeta[]>([]);
const [actingAccount, setActingAccount] = useState<InjectedAccountWithMeta>();
const [extensionInstalled, setExtensionInstalled] = useState(false);
const [injector, setInjector] = useState<InjectedExtension>()
const extensionSetup = async () => {
const { web3Accounts, web3Enable, web3FromAddress } = await import(
"@polkadot/extension-dapp"
);
const extensions = await web3Enable("Tokengated Polkadot Demo")
console.log( 'extensions', extensions )
if (extensions.length === 0) {
return;
}
setExtensionInstalled( true )
const accounts = await web3Accounts()
setAccounts(accounts)
setActingAccount(accounts[0])
// we can use web3FromSource which will return an InjectedExtension type
if ( accounts.length > 0 ) {
// the address we use to use for signing, as injected
// finds an injector for an address
const injector = await web3FromAddress(accounts[0].address);
setInjector( injector )
}
};
const onSelectAccount = ( address: any ) => {
console.log( 'onselectaccount', address )
setActingAccount( accounts?.find( a => a.address === address ) )
}
return { accounts, actingAccount, setActingAccount, extensionInstalled, onSelectAccount, injector }
}
\ No newline at end of file
...@@ -63,15 +63,19 @@ export const authOptions: NextAuthOptions = { ...@@ -63,15 +63,19 @@ export const authOptions: NextAuthOptions = {
try { try {
const message = JSON.parse(credentials.message) const message = JSON.parse(credentials.message)
//TODO verify the domain // verify the message is from the same domain
if ( message.uri !== process.env.NEXTAUTH_URL ) {
return Promise.reject(new Error('🚫 You shall not pass!'))
}
//verify the nonce // verify the message was not compromised
if (message.nonce !== credentials.csrfToken ) { if (message.nonce !== credentials.csrfToken ) {
return Promise.reject(new Error('🚫 You shall not pass!')) return Promise.reject(new Error('🚫 You shall not pass!'))
} }
// verify signature of the message // verify signature of the message
const { isValid } = signatureVerify(credentials.message, credentials.signature, credentials.address); const { isValid } = signatureVerify(credentials.message, credentials.signature, credentials.address);
if ( ! isValid ) { if ( ! isValid ) {
return Promise.reject(new Error('🚫 Invalid Signature')) return Promise.reject(new Error('🚫 Invalid Signature'))
} }
...@@ -109,7 +113,7 @@ export const authOptions: NextAuthOptions = { ...@@ -109,7 +113,7 @@ export const authOptions: NextAuthOptions = {
// maxAge: 3, // uncomment to test session expiration in seconds // maxAge: 3, // uncomment to test session expiration in seconds
}, },
jwt: { jwt: {
secret: "not very secret", secret: process.env.NEXTAUTH_SECRET,
}, },
callbacks: { callbacks: {
async jwt({ token, user }) { async jwt({ token, user }) {
...@@ -121,8 +125,6 @@ export const authOptions: NextAuthOptions = { ...@@ -121,8 +125,6 @@ export const authOptions: NextAuthOptions = {
async session(sessionData) { async session(sessionData) {
const { session, token } = sessionData const { session, token } = sessionData
console.log( 'sessionData', sessionData)
session.address = token.sub session.address = token.sub
if ( session.address ) { if ( session.address ) {
session.ksmAddress = encodeAddress( session.address, 2 ) session.ksmAddress = encodeAddress( session.address, 2 )
...@@ -135,7 +137,7 @@ export const authOptions: NextAuthOptions = { ...@@ -135,7 +137,7 @@ export const authOptions: NextAuthOptions = {
return session return session
}, },
}, },
secret: "not very secret", secret: process.env.NEXTAUTH_SECRET,
pages: { pages: {
signIn: '/', signIn: '/',
signOut: '/', signOut: '/',
......
...@@ -5,15 +5,11 @@ import styles from '@/styles/Home.module.css' ...@@ -5,15 +5,11 @@ import styles from '@/styles/Home.module.css'
import LoginButton from '@/components/login' import LoginButton from '@/components/login'
import { useSession } from 'next-auth/react' import { useSession } from 'next-auth/react'
import { usePolkadotExtension } from '@/hooks/usePolkadotExtension'
import Link from 'next/link' import Link from 'next/link'
const inter = Inter({ subsets: ['latin'] }) const inter = Inter({ subsets: ['latin'] })
export default function Home() { export default function Home() {
const { data: session } = useSession()
const { actingAccount, injector } = usePolkadotExtension()
return ( return (
<> <>
<Head> <Head>
...@@ -63,12 +59,6 @@ export default function Home() { ...@@ -63,12 +59,6 @@ export default function Home() {
🔐 Go to /protected 🔐 Go to /protected
</Link> </Link>
</div> </div>
<pre className={ styles.sessionDebug }>
session: {JSON.stringify(session, null, 2)}<br />
actingAccount: { JSON.stringify( actingAccount, null, 2 ) }<br />
injector: {JSON.stringify(injector, null, 2)}
</pre>
</main> </main>
</> </>
) )
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment