Signup with sdk

This commit is contained in:
Gilbert
2024-04-23 21:21:58 -05:00
parent 748ca507da
commit c395be82b5
38 changed files with 3240 additions and 328 deletions
+2
View File
@@ -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",
+3 -6
View File
@@ -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
+2 -6
View File
@@ -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) {
+22 -29
View File
@@ -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());
+13 -5
View File
@@ -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));