Skip to content
Open
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
11 changes: 11 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
####################
# REQUIRED
KEYP_CLIENT_ID=
TOKEN_SECRET=
# Domain where app is served
NEXTAUTH_URL=http://localhost:3002

####################
# Optional (local testing)
# NODE_TLS_REJECT_UNAUTHORIZED makes TLS connections and HTTPS requests insecure by disabling certificate verification
NODE_TLS_REJECT_UNAUTHORIZED=0
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,5 @@ yarn-error.log*
*.tsbuildinfo
next-env.d.ts

pnpm-lock.yaml
pnpm-lock.yaml
.env
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"typescript.tsdk": "node_modules/.pnpm/typescript@4.9.4/node_modules/typescript/lib",
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true
}
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,25 @@
# Juicebox x Feather test

# Setup

## Install

```bash
yarn
```

## Keyp Setup

1. Copy the file `.sample-env` to `.env`
2. Create a new application on on https://dev.usekeyp.com.

- Set the redirect URI to `http://localhost:3000/api/auth/callback/keyp` (note that your port may be different). Ready for production? Make sure to upate this to eg. `https://my-site.com/api/auth/callback/keyp`.
- Copy the "CLIENT ID" for your application and set it to `KEYP_CLIENT_ID` in `.env`

3. In the `.env`, set `TOKEN_SECRET` to a random string, which is used for `next-auth` session cookies. You can generate this using `openssl rand -base64 32`. (NOTE: Do not use your access token here)

# Run

```bash
yarn dev
```
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"ethers": "^5.7.2",
"graphql": "^16.6.0",
"next": "13.1.2",
"next-auth": "^4.19.2",
"react": "18.2.0",
"react-dom": "18.2.0",
"typescript": "4.9.4",
Expand Down
3 changes: 0 additions & 3 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import { Inter } from "@next/font/google";
import styles from "./page.module.css";

Expand All @@ -9,7 +8,6 @@ import useProject from "@/hooks/useProject";
const inter = Inter({ subsets: ["latin"] });

export default function Home(props: any) {

return (
<main className={styles.main}>
<div className={styles.content}>
Expand All @@ -19,7 +17,6 @@ export default function Home(props: any) {
Interact with 🧃Juicebox projects without a pre-existing wallet using
🪶Feather
</p>

<SearchBox />
{/* <Card /> */}
</div>
Expand Down
65 changes: 65 additions & 0 deletions src/components/NavBar/NavBar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import Link from "next/link";
import { useSession, signIn, signOut } from "next-auth/react";

export default function Navbar() {
const [user, { mutate }] = useUser();

const { data: session } = useSession();

async function handleLogout() {
await fetch("/api/logout");
mutate({ user: null });
}

return (
<header>
<nav>
<ul>
<li>
<Link href="/" legacyBehavior>
Home
</Link>
</li>
{session ? (
<>
Signed in as {session.user.username} <br />
<button onClick={() => signOut()}>Sign out</button>
</>
) : (
<li>
<button onClick={() => signIn()}>Login</button>
</li>
)}
</ul>
</nav>
<style jsx>{`
nav {
max-width: 42rem;
margin: 0 auto;
padding: 0.2rem 1.25rem;
}
ul {
display: flex;
list-style: none;
margin-left: 0;
padding-left: 0;
}
li {
margin-right: 1rem;
}
li:first-child {
margin-left: auto;
}
a {
color: #fff;
text-decoration: none;
cursor: pointer;
}
header {
color: #fff;
background-color: #666;
}
`}</style>
</header>
);
}
11 changes: 11 additions & 0 deletions src/pages/_app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { SessionProvider } from "next-auth/react";

function MyApp({ Component, pageProps: { session, ...pageProps } }) {
return (
<SessionProvider session={session}>
<Component {...pageProps} />
</SessionProvider>
);
}

export default MyApp;
59 changes: 59 additions & 0 deletions src/pages/api/auth/[...nextauth].js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import NextAuth from "next-auth";

const KEYP_APP_DOMAIN = "https://app.usekeyp.com";
// const KEYP_APP_DOMAIN = "https://localhost";
// const KEYP_APP_DOMAIN = "https://api.staging-env.usekeyp.com";

const KeypProvider = {
id: "keyp",
name: "Keyp",
type: "oauth",
version: "2.0",
clientId: process.env.KEYP_CLIENT_ID,
wellKnown: `${KEYP_APP_DOMAIN}/oauth/.well-known/openid-configuration`,
checks: ["pkce"],
authorization: { params: { scope: "openid email" } },
client: { token_endpoint_auth_method: "none" },
profile(profile) {
return {
id: profile.sub,
username: profile.username,
address: profile.address,
email: profile.email,
imageSrc: profile.imageSrc,
};
},
};

export default NextAuth({
pages: {
signIn: "/login",
error: "/login", // Error code passed in query string as ?error=
},
secret: process.env.TOKEN_SECRET,
providers: [KeypProvider],
callbacks: {
async jwt({ token, account, profile }) {
if (account) {
// Comes from the returned JWT from Keyp
token.accessToken = account.access_token;
}
if (profile) {
// Comes from the /userinfo endpoint
token.username = profile.username;
token.address = profile.address;
}
return token;
},
async session({ session, token }) {
// Send properties to the client, like an access_token from a provider.
if (token) {
session.user.accessToken = token.accessToken;
session.user.username = token.username;
session.user.address = token.address;
session.user.id = token.sub;
}
return session;
},
},
});
13 changes: 0 additions & 13 deletions src/pages/api/hello.ts

This file was deleted.

37 changes: 37 additions & 0 deletions src/pages/login.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { useState, useEffect } from "react";
import Link from "next/link";
import { useSession, signIn, signOut } from "next-auth/react";

export default function LoginPage() {
const { data: session } = useSession();

if (session) {
return (
<>
Signed in as {session.user.username} <br />
<button onClick={() => signOut()}>Sign out</button>
</>
);
}

return (
<>
<h1>Login to Example</h1>
<div className="form-container">
<div className="submit">
<button onClick={() => signIn("keyp", null, "login_provider=GOOGLE")}>
Log in with Google
</button>
<button
onClick={() => signIn("keyp", null, "login_provider=DISCORD")}
>
Log in with Discord
</button>
<button onClick={() => signIn("keyp", null, "login_provider=CHESS")}>
Log in with Chess
</button>
</div>
</div>
</>
);
}
Loading