Skip to content

Commit

Permalink
šŸ€šŸŒ±Ā ā†£ Add new routes for auth handling, new plans & continuing Vite miā€¦
Browse files Browse the repository at this point in the history
  • Loading branch information
Gizmotronn committed Dec 24, 2022
1 parent 6967f5c commit bfd45cd
Show file tree
Hide file tree
Showing 30 changed files with 10,317 additions and 11,143 deletions.
Binary file modified .DS_Store
Binary file not shown.
3 changes: 2 additions & 1 deletion Server/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
env
.vscode
.vscode
.env
28 changes: 0 additions & 28 deletions Server/Home/package.json

This file was deleted.

10,976 changes: 0 additions & 10,976 deletions Server/Home/yarn.lock

This file was deleted.

4 changes: 3 additions & 1 deletion Server/Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ name = "pypi"
moralis = "*"
flask = "*"
flask_cors = "*"
thirdweb-sdk = "*"

This comment has been minimized.

Copy link
@Gizmotronn

Gizmotronn Dec 24, 2022

Author Member

#19 #20 #16 #13

Other commits in this branch (and the branch wb3-5-take-user-inputs-for-minting-via-flask also reference these issues (and occasionally #18). Check Linear.app for more

python-dotenv = "*"

[dev-packages]

[requires]
python_version = "3.10"
python_version = "3.10"
1,161 changes: 1,157 additions & 4 deletions Server/Pipfile.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Server/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Make sure to initialise the Flask app with `pipenv` and run the command `export FLASK_APP=app.py`
113 changes: 64 additions & 49 deletions Server/app.py
Original file line number Diff line number Diff line change
@@ -1,57 +1,72 @@
from flask import Flask
from flask import request
from moralis import auth
from flask_cors import CORS
from flask import Flask, request, make_response, jsonify
from thirdweb.types import LoginPayload
from thirdweb import ThirdwebSDK
from datetime import datetime, timedelta
import os

# Flask application setup
app = Flask(__name__)
CORS(app)
apiKey = "kJfYYpmMmfKhvaWMdD3f3xMMb24B4MHBDDVrfjslkKgTilvMgdwr1bwKUr8vWdHH" # Move to env

# Authentication routes -> move to auth.py later
# Request a challenge when a user attempts to connect their wallet
@app.route('/requestChallenge', methods=['GET'])
def reqChallenge():
args = request.args # Fetch the arguments from the request

# Get request body -> compare with data from Moralis
body = {
"domain": "sailors.skinetics.tech",
"chainId": args.get("chainId"),
"address": args.get("address"),
"statement": "Please confirm authentication by signing this transaction",
"uri": "https://ipfs.skinetics.tech/auth/1...",
"expirationTime": "2023-01-01T00:00:00.000Z",
"notBefore": "2020-01-01T00:00:00.000Z",
"resources": ['https://docs.skinetics.tech/crypto/auth/signing'],
"timeout": 30,
}

# Deliver the result to Moralis client
result = auth.challenge.request_challenge_evm(
api_key=apiKey,
body=body,
)

return result
@app.route('/', methods=["GET"])
def index():
return "Hello World"

@app.route('/login', methods=['POST'])
def login():
private_key = os.environ.get("PRIVATE_KEY")

if not private_key:
print("Missing PRIVATE_KEY environment variable")
return "Wallet private key not set", 400

# Verify signature from user
@app.route('/verifyChallenge', methods=['GET'])
def verifyChallenge():
args = request.args
sdk = ThirdwebSDK.from_private_key(private_key, 'mumbai') # Initialise the sdk using the wallet and on mumbai testnet chain
payload = LoginPayload.from_json(request.json['payload'])

body = { # Request body
"message": args.get("message"),
"signature": args.get("signature"),
},
# Generate access token using signed payload
domain = 'sailors.skinetics.tech'
token = sdk.auth.generate_auth_token(domain, payload)

res = make_response()
res.set_cookie(
'access_token',
token,
path='/',
httponly=True,
secure=True,
samesite='strict',
)
return res, 200

result = auth.challenge.verify_challenge_evm(
api_key=apiKey,
body=body,
),
@app.route('/authenticate', methods=['POST'])
def authenticate():
private_key = os.environ.get("PRIVATE_KEY")

if not private_key:
print("Missing PRIVATE_KEY environment variable")
return "Wallet private key not set", 400

return result
sdk = ThirdwebSDK.from_private_key(private_key, 'mumbai')

# Initialising Flask application
if __name__ == '__main__':
app.run(host='127.0.0.1', port='5000', debug=True)
# Get access token from cookies
token = request.cookies.get('access_token')
if not token:
return 'Unauthorised', 401

domain = 'sailors.skinetics.tech'

try:
address = sdk.auth.authenticate(domain, token)
except:
return "Unauthorized", 401

print(jsonify(address))
return jsonify(address), 200

@app.route('/logout', methods=['POST'])
def logout():
res = make_response()
res.set_cookie(
'access_token',
'none',
expires=datetime.utcnow() + timedelta(second = 5)
)
return res, 200
3 changes: 3 additions & 0 deletions Server/frontend/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}
36 changes: 36 additions & 0 deletions Server/frontend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
36 changes: 36 additions & 0 deletions Server/frontend/hooks/useAuthenticate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { useSDK } from '@thirdweb-dev/react';

export default function useAuthenticate() {
const domain = 'sailors.skinetics.tech';
const sdk = useSDK();

async function login() {
const payload = await sdk?.auth.login(domain);
await fetch("/api/login", {
method: "POST",
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ payload }),
});
}

async function authenticate() {
const res = await fetch("/api/authenticate", {
method: "POST",
});
return res; // From flask server/api
}

async function logout() {
await fetch("/api/logout", {
method: "POST",
});
}

return {
login,
authenticate,
logout,
};
}
14 changes: 14 additions & 0 deletions Server/frontend/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
async rewrites() {
return [
{
source: '/api/:path*',
destination: 'http://localhost:5000/:path*' // Proxy to Backend
}
]
}
}

module.exports = nextConfig;
29 changes: 29 additions & 0 deletions Server/frontend/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "sailors-auth-frontend",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@supabase/supabase-js": "^2.2.2",
"@thirdweb-dev/auth": "^2.0.38",
"@thirdweb-dev/react": "^3.6.8",
"@thirdweb-dev/sdk": "^3.6.8",
"ethers": "^5.7.2",
"next": "13.1.0",
"react": "18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/cookie": "^0.5.1",
"@types/node": "^17.0.35",
"@types/react": "^17.0.45",
"eslint": "8.30.0",
"eslint-config-next": "13.1.0",
"typescript": "^4.7.2"
}
}
21 changes: 21 additions & 0 deletions Server/frontend/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { AppProps } from "next/app";
import { ChainId, ThirdwebProvider } from "@thirdweb-dev/react";

const activeChainId = ChainId.Mumbai;

function MyApp({ Component, pageProps }: AppProps) {
return (
<ThirdwebProvider
desiredChainId={activeChainId}
authConfig={{
domain: "sailors.skinetics.tech",
authUrl: "/api/auth",
loginRedirect: "/"
}}
>
<Component {...pageProps} />
</ThirdwebProvider>
)
}

export default MyApp;
43 changes: 43 additions & 0 deletions Server/frontend/pages/api/auth/[...thirdweb].ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { ThirdwebAuth } from "@thirdweb-dev/auth/next";
import { createClient } from '@supabase/supabase-js';

export const supabase = createClient(
process.env.SUPABASE_URL || "",
process.env.SUPABASE_SERVICE_ROLE || ""
);

export const { ThirdwebAuthHandler, getUser } = ThirdwebAuth({
privateKey: process.env.PRIVATE_KEY || "",
domain: "sailors.skinetics.tech",
callbacks: {
login: async (address: string) => {
const { data: user } = await supabase
.from("users")
.select("*")
.eq("address", address.toLowerCase())
.single();

if (!user) {
const res = await supabase
.from("users")
.insert({ address: address.toLowerCase() })
.single();

if (res.error) {
throw new Error("Failed to create user!");
}
}
},
user: async (address: string) => {
const { data: user } = await supabase
.from("users")
.select("*")
.eq("address", address.toLowerCase())
.single();

return user;
},
},
});

export default ThirdwebAuthHandler();
Loading

0 comments on commit bfd45cd

Please sign in to comment.