forked from cerc-io/snowballtools-base
Signup with sdk
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
"@types/semver": "^7.5.8",
|
||||
"apollo-server-core": "^3.13.0",
|
||||
"apollo-server-express": "^3.13.0",
|
||||
"cookie-session": "^2.1.0",
|
||||
"cors": "^2.8.5",
|
||||
"debug": "^4.3.1",
|
||||
"express": "^4.18.2",
|
||||
@@ -45,6 +46,7 @@
|
||||
"test:db:delete": "DEBUG=snowball:* ts-node ./test/delete-db.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/cookie-session": "^2.0.49",
|
||||
"@types/express-session": "^1.17.10",
|
||||
"@types/fs-extra": "^11.0.4",
|
||||
"better-sqlite3": "^9.2.2",
|
||||
|
||||
@@ -9,8 +9,6 @@ import { Database } from './database';
|
||||
import { createAndStartServer } from './server';
|
||||
import { createResolvers } from './resolvers';
|
||||
import { getConfig } from './utils';
|
||||
import { Config } from './config';
|
||||
import { DEFAULT_CONFIG_FILE_PATH } from './constants';
|
||||
import { Service } from './service';
|
||||
import { Registry } from './registry';
|
||||
|
||||
@@ -18,13 +16,12 @@ const log = debug('snowball:server');
|
||||
const OAUTH_CLIENT_TYPE = 'oauth-app';
|
||||
|
||||
export const main = async (): Promise<void> => {
|
||||
// TODO: get config path using cli
|
||||
const { server, database, gitHub, registryConfig, misc } = await getConfig<Config>(DEFAULT_CONFIG_FILE_PATH);
|
||||
const { server, database, gitHub, registryConfig, misc } = await getConfig();
|
||||
|
||||
const app = new OAuthApp({
|
||||
clientType: OAUTH_CLIENT_TYPE,
|
||||
clientId: gitHub.oAuth.clientId,
|
||||
clientSecret: gitHub.oAuth.clientSecret
|
||||
clientSecret: gitHub.oAuth.clientSecret,
|
||||
});
|
||||
|
||||
const db = new Database(database, misc);
|
||||
@@ -35,7 +32,7 @@ export const main = async (): Promise<void> => {
|
||||
{ gitHubConfig: gitHub, registryConfig },
|
||||
db,
|
||||
app,
|
||||
registry
|
||||
registry,
|
||||
);
|
||||
|
||||
const typeDefs = fs
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
import { Router } from 'express';
|
||||
import { SiweMessage, generateNonce } from 'siwe';
|
||||
import { SiweMessage } from 'siwe';
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.get('/nonce', async (_, res) => {
|
||||
res.send(generateNonce());
|
||||
});
|
||||
|
||||
router.post('/validate', async (req, res) => {
|
||||
const { message, signature } = req.body;
|
||||
const { success, data } = await new SiweMessage(message).verify({
|
||||
signature
|
||||
signature,
|
||||
});
|
||||
|
||||
if (success) {
|
||||
|
||||
@@ -6,9 +6,9 @@ import { createServer } from 'http';
|
||||
import {
|
||||
ApolloServerPluginDrainHttpServer,
|
||||
ApolloServerPluginLandingPageLocalDefault,
|
||||
AuthenticationError
|
||||
AuthenticationError,
|
||||
} from 'apollo-server-core';
|
||||
import session from 'express-session';
|
||||
import cookieSession from 'cookie-session';
|
||||
|
||||
import { TypeSource } from '@graphql-tools/utils';
|
||||
import { makeExecutableSchema } from '@graphql-tools/schema';
|
||||
@@ -32,7 +32,7 @@ export const createAndStartServer = async (
|
||||
serverConfig: ServerConfig,
|
||||
typeDefs: TypeSource,
|
||||
resolvers: any,
|
||||
service: Service
|
||||
service: Service,
|
||||
): Promise<ApolloServer> => {
|
||||
const { host, port, gqlPath = DEFAULT_GQL_PATH } = serverConfig;
|
||||
const { appOriginUrl, secret, domain, trustProxy } = serverConfig.session;
|
||||
@@ -45,7 +45,7 @@ export const createAndStartServer = async (
|
||||
// Create the schema
|
||||
const schema = makeExecutableSchema({
|
||||
typeDefs,
|
||||
resolvers
|
||||
resolvers,
|
||||
});
|
||||
|
||||
const server = new ApolloServer({
|
||||
@@ -68,32 +68,18 @@ export const createAndStartServer = async (
|
||||
plugins: [
|
||||
// Proper shutdown for the HTTP server
|
||||
ApolloServerPluginDrainHttpServer({ httpServer }),
|
||||
ApolloServerPluginLandingPageLocalDefault({ embed: true })
|
||||
]
|
||||
ApolloServerPluginLandingPageLocalDefault({ embed: true }),
|
||||
],
|
||||
});
|
||||
|
||||
await server.start();
|
||||
|
||||
app.use(cors({
|
||||
origin: appOriginUrl,
|
||||
credentials: true
|
||||
}));
|
||||
|
||||
const sessionOptions: session.SessionOptions = {
|
||||
secret: secret,
|
||||
resave: false,
|
||||
saveUninitialized: true,
|
||||
cookie: {
|
||||
secure: new URL(appOriginUrl).protocol === 'https:',
|
||||
// TODO: Set cookie maxAge and handle cookie expiry in frontend
|
||||
// maxAge: SESSION_COOKIE_MAX_AGE,
|
||||
sameSite: new URL(appOriginUrl).protocol === 'https:' ? 'none' : 'lax'
|
||||
}
|
||||
};
|
||||
|
||||
if (domain) {
|
||||
sessionOptions.cookie!.domain = domain;
|
||||
}
|
||||
app.use(
|
||||
cors({
|
||||
origin: appOriginUrl,
|
||||
credentials: true,
|
||||
}),
|
||||
);
|
||||
|
||||
if (trustProxy) {
|
||||
// trust first proxy
|
||||
@@ -101,7 +87,14 @@ export const createAndStartServer = async (
|
||||
}
|
||||
|
||||
app.use(
|
||||
session(sessionOptions)
|
||||
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,
|
||||
}),
|
||||
);
|
||||
|
||||
server.applyMiddleware({
|
||||
@@ -109,8 +102,8 @@ export const createAndStartServer = async (
|
||||
path: gqlPath,
|
||||
cors: {
|
||||
origin: [appOriginUrl],
|
||||
credentials: true
|
||||
}
|
||||
credentials: true,
|
||||
},
|
||||
});
|
||||
|
||||
app.use(express.json());
|
||||
|
||||
@@ -3,11 +3,18 @@ import path from 'path';
|
||||
import toml from 'toml';
|
||||
import debug from 'debug';
|
||||
import { DataSource, DeepPartial, EntityTarget, ObjectLiteral } from 'typeorm';
|
||||
import { Config } from './config';
|
||||
import { DEFAULT_CONFIG_FILE_PATH } from './constants';
|
||||
|
||||
const log = debug('snowball:utils');
|
||||
|
||||
export const getConfig = async <ConfigType>(
|
||||
configFile: string
|
||||
export async function getConfig() {
|
||||
// TODO: get config path using cli
|
||||
return await _getConfig<Config>(DEFAULT_CONFIG_FILE_PATH);
|
||||
}
|
||||
|
||||
const _getConfig = async <ConfigType>(
|
||||
configFile: string,
|
||||
): Promise<ConfigType> => {
|
||||
const configFilePath = path.resolve(configFile);
|
||||
const fileExists = await fs.pathExists(configFilePath);
|
||||
@@ -41,7 +48,7 @@ export const loadAndSaveData = async <Entity extends ObjectLiteral>(
|
||||
entityType: EntityTarget<Entity>,
|
||||
dataSource: DataSource,
|
||||
entities: any,
|
||||
relations?: any | undefined
|
||||
relations?: any | undefined,
|
||||
): Promise<Entity[]> => {
|
||||
const entityRepository = dataSource.getRepository(entityType);
|
||||
|
||||
@@ -56,7 +63,7 @@ export const loadAndSaveData = async <Entity extends ObjectLiteral>(
|
||||
|
||||
entity = {
|
||||
...entity,
|
||||
[field]: relations[field][entityData[valueIndex]]
|
||||
[field]: relations[field][entityData[valueIndex]],
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -67,4 +74,5 @@ export const loadAndSaveData = async <Entity extends ObjectLiteral>(
|
||||
return savedEntity;
|
||||
};
|
||||
|
||||
export const sleep = async (ms: number): Promise<void> => new Promise(resolve => setTimeout(resolve, ms));
|
||||
export const sleep = async (ms: number): Promise<void> =>
|
||||
new Promise((resolve) => setTimeout(resolve, ms));
|
||||
|
||||
Reference in New Issue
Block a user