forked from cerc-io/snowballtools-base
Implement authentication with SIWE (#4)
Part of [Service provider auctions for web deployments](https://www.notion.so/Service-provider-auctions-for-web-deployments-104a6b22d47280dbad51d28aa3a91d75) - Remove LIT authentication Co-authored-by: Neeraj <neeraj.rtly@gmail.com> Reviewed-on: cerc-io/snowballtools-base#4
This commit is contained in:
@@ -5,19 +5,6 @@ import { authenticateUser, createUser } from '../turnkey-backend';
|
||||
|
||||
const router = Router();
|
||||
|
||||
//
|
||||
// Access Code
|
||||
//
|
||||
router.post('/accesscode', async (req, res) => {
|
||||
console.log('Access Code', req.body);
|
||||
const { accesscode } = req.body;
|
||||
if (accesscode === '44444') {
|
||||
return res.send({ isValid: true });
|
||||
} else {
|
||||
return res.sendStatus(204);
|
||||
}
|
||||
});
|
||||
|
||||
//
|
||||
// Turnkey
|
||||
//
|
||||
@@ -40,7 +27,7 @@ router.post('/register', async (req, res) => {
|
||||
userEmail: email,
|
||||
userName: email.split('@')[0],
|
||||
});
|
||||
req.session.userId = user.id;
|
||||
req.session.address = user.id;
|
||||
res.sendStatus(200);
|
||||
});
|
||||
|
||||
@@ -52,19 +39,15 @@ router.post('/authenticate', async (req, res) => {
|
||||
signedWhoamiRequest,
|
||||
);
|
||||
if (user) {
|
||||
req.session.userId = user.id;
|
||||
req.session.address = user.id;
|
||||
res.sendStatus(200);
|
||||
} else {
|
||||
res.sendStatus(401);
|
||||
}
|
||||
});
|
||||
|
||||
//
|
||||
// Lit
|
||||
//
|
||||
|
||||
router.post('/validate', async (req, res) => {
|
||||
const { message, signature, action } = req.body;
|
||||
const { message, signature } = req.body;
|
||||
const { success, data } = await new SiweMessage(message).verify({
|
||||
signature,
|
||||
});
|
||||
@@ -75,10 +58,7 @@ router.post('/validate', async (req, res) => {
|
||||
const service: Service = req.app.get('service');
|
||||
const user = await service.getUserByEthAddress(data.address);
|
||||
|
||||
if (action === 'signup') {
|
||||
if (user) {
|
||||
return res.send({ success: false, error: 'user_already_exists' });
|
||||
}
|
||||
if (!user) {
|
||||
const newUser = await service.createUser({
|
||||
ethAddress: data.address,
|
||||
email: '',
|
||||
@@ -86,12 +66,12 @@ router.post('/validate', async (req, res) => {
|
||||
subOrgId: '',
|
||||
turnkeyWalletId: '',
|
||||
});
|
||||
req.session.userId = newUser.id;
|
||||
} else if (action === 'login') {
|
||||
if (!user) {
|
||||
return res.send({ success: false, error: 'user_not_found' });
|
||||
}
|
||||
req.session.userId = user.id;
|
||||
// SIWESession from the web3modal library requires both address and chain ID
|
||||
req.session.address = newUser.id;
|
||||
req.session.chainId = data.chainId;
|
||||
} else {
|
||||
req.session.address = user.id;
|
||||
req.session.chainId = data.chainId;
|
||||
}
|
||||
|
||||
res.send({ success });
|
||||
@@ -101,9 +81,10 @@ router.post('/validate', async (req, res) => {
|
||||
// General
|
||||
//
|
||||
router.get('/session', (req, res) => {
|
||||
if (req.session.userId) {
|
||||
if (req.session.address && req.session.chainId) {
|
||||
res.send({
|
||||
userId: req.session.userId,
|
||||
address: req.session.address,
|
||||
chainId: req.session.chainId
|
||||
});
|
||||
} else {
|
||||
res.status(401).send({ error: 'Unauthorized: No active session' });
|
||||
@@ -111,9 +92,12 @@ router.get('/session', (req, res) => {
|
||||
});
|
||||
|
||||
router.post('/logout', (req, res) => {
|
||||
// This is how you clear cookie-session
|
||||
(req as any).session = null;
|
||||
res.send({ success: true });
|
||||
req.session.destroy((err) => {
|
||||
if (err) {
|
||||
return res.send({ success: false });
|
||||
}
|
||||
res.send({ success: true });
|
||||
});
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
ApolloServerPluginLandingPageLocalDefault,
|
||||
AuthenticationError,
|
||||
} from 'apollo-server-core';
|
||||
import cookieSession from 'cookie-session';
|
||||
import session from 'express-session';
|
||||
|
||||
import { TypeSource } from '@graphql-tools/utils';
|
||||
import { makeExecutableSchema } from '@graphql-tools/schema';
|
||||
@@ -22,9 +22,13 @@ import { Service } from './service';
|
||||
|
||||
const log = debug('snowball:server');
|
||||
|
||||
// Set cookie expiration to 1 month in milliseconds
|
||||
const COOKIE_MAX_AGE = 30 * 24 * 60 * 60 * 1000;
|
||||
|
||||
declare module 'express-session' {
|
||||
interface SessionData {
|
||||
userId: string;
|
||||
address: string;
|
||||
chainId: number;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,14 +58,13 @@ export const createAndStartServer = async (
|
||||
context: async ({ req }) => {
|
||||
// https://www.apollographql.com/docs/apollo-server/v3/security/authentication#api-wide-authorization
|
||||
|
||||
const { userId } = req.session;
|
||||
const { address } = req.session;
|
||||
|
||||
if (!userId) {
|
||||
if (!address) {
|
||||
throw new AuthenticationError('Unauthorized: No active session');
|
||||
}
|
||||
|
||||
const user = await service.getUser(userId);
|
||||
|
||||
const user = await service.getUser(address);
|
||||
return { user };
|
||||
},
|
||||
plugins: [
|
||||
@@ -80,20 +83,25 @@ export const createAndStartServer = async (
|
||||
}),
|
||||
);
|
||||
|
||||
const sessionOptions: session.SessionOptions = {
|
||||
secret: secret,
|
||||
resave: false,
|
||||
saveUninitialized: true,
|
||||
cookie: {
|
||||
secure: new URL(appOriginUrl).protocol === 'https:',
|
||||
maxAge: COOKIE_MAX_AGE,
|
||||
domain: domain || undefined,
|
||||
sameSite: new URL(appOriginUrl).protocol === 'https:' ? 'none' : 'lax',
|
||||
}
|
||||
};
|
||||
|
||||
if (trustProxy) {
|
||||
// trust first proxy
|
||||
app.set('trust proxy', 1);
|
||||
}
|
||||
|
||||
app.use(
|
||||
cookieSession({
|
||||
secret: secret,
|
||||
secure: new URL(appOriginUrl).protocol === 'https:',
|
||||
// 23 hours (less than 24 hours to avoid sessionSigs expiration issues)
|
||||
maxAge: 23 * 60 * 60 * 1000,
|
||||
sameSite: new URL(appOriginUrl).protocol === 'https:' ? 'none' : 'lax',
|
||||
domain: domain || undefined,
|
||||
}),
|
||||
session(sessionOptions)
|
||||
);
|
||||
|
||||
server.applyMiddleware({
|
||||
|
||||
Reference in New Issue
Block a user