Clean up and autogenerate TS from GQL
This commit is contained in:
parent
ac4d30ecdf
commit
33b0e8313c
|
@ -0,0 +1,11 @@
|
|||
schema: src/schema.graphql
|
||||
overwrite: true
|
||||
generates:
|
||||
./src/types.gen.d.ts:
|
||||
config:
|
||||
noNamespace: true
|
||||
fieldResolverNamePrefix: Field
|
||||
plugins:
|
||||
- typescript-common
|
||||
- typescript-server
|
||||
- typescript-resolvers
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"name": "functions",
|
||||
"scripts": {
|
||||
"codegen": "gql-gen",
|
||||
"lint": "tslint --project tsconfig.json",
|
||||
"build": "tsc --version && tsc",
|
||||
"start": "ts-node src/index.ts"
|
||||
|
@ -44,10 +45,14 @@
|
|||
"@types/joi": "^13.0.8",
|
||||
"@types/node": "^9.6.1",
|
||||
"@types/node-fetch": "^2.1.1",
|
||||
"graphql-code-generator": "^0.16.0",
|
||||
"graphql-codegen-typescript-common": "^0.16.0",
|
||||
"graphql-codegen-typescript-resolvers": "^0.16.0",
|
||||
"graphql-codegen-typescript-server": "^0.16.0",
|
||||
"ts-jest": "23.10.3",
|
||||
"ts-node": "^7.0.1",
|
||||
"tslint": "^5.9.1",
|
||||
"typescript": "^3.1.1"
|
||||
"typescript": "^3.2.4"
|
||||
},
|
||||
"jest": {
|
||||
"moduleFileExtensions": [
|
||||
|
|
|
@ -3,13 +3,6 @@ import {User} from "../types";
|
|||
import UserManager from "../user";
|
||||
import SessionManager from "../session";
|
||||
|
||||
interface AuthQueryResolvers {
|
||||
}
|
||||
|
||||
|
||||
interface AuthMutationResolvers {
|
||||
}
|
||||
|
||||
export default class AuthResolvers {
|
||||
userManager: UserManager
|
||||
repository: Repository
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import {auth} from 'google-auth-library';
|
||||
import Repository from "../repository";
|
||||
import {OAuth2Client} from "google-auth-library/build/src/auth/oauth2client";
|
||||
import {atob} from 'atob';
|
||||
import {CalendarEvent} from "../types";
|
||||
|
|
|
@ -1,74 +0,0 @@
|
|||
import {Request, Response} from "express";
|
||||
import CalendarManager from './calendar';
|
||||
import SessionManager from "./session";
|
||||
import {AuthenticatedRequest, authRequest} from "./authRequest";
|
||||
import {CalendarEvent} from "./types";
|
||||
import EventManager from "./event";
|
||||
|
||||
let sessionManager: SessionManager, calendarManager: CalendarManager, eventManager: EventManager
|
||||
export type Dependencies = {
|
||||
sessionManager: SessionManager
|
||||
calendarManager: CalendarManager,
|
||||
eventManager: EventManager,
|
||||
}
|
||||
|
||||
export const setDependencies = (dependencies: Dependencies) => {
|
||||
sessionManager = dependencies.sessionManager
|
||||
calendarManager = dependencies.calendarManager
|
||||
eventManager = dependencies.eventManager
|
||||
}
|
||||
|
||||
export const getEvents = async (req: Request, res: Response) => {
|
||||
let result
|
||||
try {
|
||||
result = await calendarManager.listEvents()
|
||||
} catch (e) {
|
||||
console.log('Caught error while listing events', e)
|
||||
res.status(500)
|
||||
res.send('Error fetching events')
|
||||
}
|
||||
res.send(result)
|
||||
res.status(200)
|
||||
}
|
||||
|
||||
export const postEvent = async (req: Request, res: Response) => {
|
||||
await authRequest(sessionManager)(req, res)
|
||||
const session = (req as AuthenticatedRequest).session
|
||||
if (!session.isValid) {
|
||||
res.send('Session expired')
|
||||
res.sendStatus(401)
|
||||
}
|
||||
|
||||
const eventData = req.body as CalendarEvent
|
||||
eventData.owner = session.userId
|
||||
const validationError = eventManager.getValidationErrors({
|
||||
...req.body,
|
||||
owner: session.userId,
|
||||
})
|
||||
if (!validationError) {
|
||||
console.log('Validation succeeded for event', eventData)
|
||||
const dbEvent = await eventManager.createEvent(eventData)
|
||||
console.log('event created with id', dbEvent.id)
|
||||
res.send({eventId: dbEvent.id})
|
||||
res.sendStatus(200)
|
||||
} else {
|
||||
console.warn('Bad request coming in', eventData, validationError)
|
||||
|
||||
res.status(400)
|
||||
res.send(validationError)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
export const events = async (req: Request, res: Response) => {
|
||||
let delegationHandler
|
||||
if (req.method === 'GET') {
|
||||
delegationHandler = getEvents
|
||||
} else if (req.method === 'POST') {
|
||||
delegationHandler = postEvent
|
||||
} else {
|
||||
res.sendStatus(400)
|
||||
return
|
||||
}
|
||||
delegationHandler(req, res)
|
||||
}
|
|
@ -1,12 +1,3 @@
|
|||
import {
|
||||
setDependencies as setUserHandlerDependencies,
|
||||
} from './userHandlers'
|
||||
|
||||
import {
|
||||
events as eventsHandler,
|
||||
setDependencies as setEventsHandlerDependencies
|
||||
} from './eventHandlers';
|
||||
|
||||
import {gcal as gcalConfig, projectId} from "./config";
|
||||
import UserManager from "./user";
|
||||
import SessionManager from "./session";
|
||||
|
@ -29,13 +20,6 @@ async function start() {
|
|||
})
|
||||
const eventManager = new EventManager({calendarManager, eventsRepository})
|
||||
|
||||
setUserHandlerDependencies({
|
||||
userManager, sessionManager
|
||||
})
|
||||
setEventsHandlerDependencies({
|
||||
sessionManager, calendarManager, eventManager
|
||||
})
|
||||
|
||||
const gql = new GraphQLInterface({
|
||||
repository,
|
||||
userManager,
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
const randomstring = require('random-string')
|
||||
import {sendEmail} from './post_office'
|
||||
import {domain} from './config'
|
||||
import { Repository } from './repository'
|
||||
import Repository from './repository'
|
||||
import {DBEntity, User} from "./types";
|
||||
|
||||
export class SessionAlreadyValidatedError extends Error {}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import Repository from './mongorepo'
|
||||
import Repository from './repository'
|
||||
import {User, UserKeys, UserProperties} from './types'
|
||||
|
||||
export default class UserManager {
|
||||
|
|
|
@ -1,150 +0,0 @@
|
|||
import {parse} from 'url'
|
||||
import UserManager from './user'
|
||||
import {Request, Response} from 'express'
|
||||
import SessionManager, {Session, SessionAlreadyValidatedError, SessionRequest} from './session'
|
||||
import {UserProperties} from './types'
|
||||
|
||||
let userManager, sessionManager
|
||||
export type Dependencies = {
|
||||
userManager: UserManager,
|
||||
sessionManager: SessionManager
|
||||
}
|
||||
|
||||
export const setDependencies = (dependencies) => {
|
||||
userManager = dependencies.userManager
|
||||
sessionManager = dependencies.sessionManager
|
||||
}
|
||||
|
||||
export const isUserAvailable = async (req: Request, res: Response) => {
|
||||
const params = parse(req.url, true).query
|
||||
|
||||
const user = await userManager.getUser({
|
||||
email: params.email as string,
|
||||
username: params.username as string
|
||||
})
|
||||
|
||||
res.send({
|
||||
exists: !!user
|
||||
});
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
const handleSignup = (async (req: Request, res: Response) => {
|
||||
const {username, email, firstName, lastName} = req.body
|
||||
const userProperties: UserProperties = {username, email, firstName, lastName}
|
||||
|
||||
let newUser
|
||||
const userKeys = {
|
||||
username, email, name
|
||||
}
|
||||
try {
|
||||
console.log(`Will try to create new user ${userKeys}`)
|
||||
newUser = await userManager.createUser(userKeys)
|
||||
} catch (e) {
|
||||
console.error('Error creating new user', userKeys, e)
|
||||
res.status(409)
|
||||
res.send(e.message)
|
||||
return
|
||||
}
|
||||
|
||||
if (!newUser) {
|
||||
res.status(409)
|
||||
res.send(`Could not create user: ${JSON.stringify(userProperties)}`)
|
||||
return
|
||||
}
|
||||
|
||||
console.log('User created', JSON.stringify(newUser))
|
||||
res.status(200)
|
||||
res.send('User created. Invitation will be sent.')
|
||||
|
||||
try {
|
||||
await sessionManager.inviteUser(newUser)
|
||||
} catch (e) {
|
||||
res.status(500)
|
||||
res.send(`Error sending invitation. ${e.message}`)
|
||||
console.error('Error sending invitation', e)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
export const signup = async (req: Request, res: Response) => {
|
||||
try {
|
||||
await handleSignup(req, res)
|
||||
} catch (e) {
|
||||
console.error('Signup handle error', e)
|
||||
res.send('Signup handle error')
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
const handleSignin = async (req: Request, res: Response) => {
|
||||
const params = req.body
|
||||
const ip = req.ip.split('.').map(num => parseInt(num))
|
||||
|
||||
console.log('Got sign in request with params', JSON.stringify(params))
|
||||
let session = null
|
||||
try {
|
||||
|
||||
session = await sessionManager.initiateSession({
|
||||
hash: params.hash as string,
|
||||
ipAddress: ip,
|
||||
userAgent: req.headers['user-agent'],
|
||||
} as SessionRequest)
|
||||
} catch (e) {
|
||||
if (e instanceof SessionAlreadyValidatedError) {
|
||||
res.status(401)
|
||||
res.send('Session already validated')
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (!session) {
|
||||
res.status(403)
|
||||
res.send('Could not initiate session with the given data')
|
||||
return
|
||||
}
|
||||
|
||||
console.log('Session initiated', JSON.stringify(session))
|
||||
res.status(200)
|
||||
res.setHeader('set-cookie', `__session=${session.hash}; Secure;`)
|
||||
res.send(`Session initiated: ${JSON.stringify(session)}`)
|
||||
}
|
||||
|
||||
export const signin = async (req: Request, res: Response) => {
|
||||
try {
|
||||
console.log('Will handle signin request')
|
||||
await handleSignin(req, res)
|
||||
} catch (e) {
|
||||
console.error('Sign-in handle error', e)
|
||||
res.send('Sign-in handle error')
|
||||
res.status(500)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
const handlePostSession = async (req: Request, res: Response) => {
|
||||
const { email } = req.body
|
||||
|
||||
console.log('Will request new session for email: ', email)
|
||||
const user = await userManager.getUser({email})
|
||||
if (!user) {
|
||||
res.status(404)
|
||||
res.send('Could not find user')
|
||||
return
|
||||
}
|
||||
await sessionManager.inviteUser(user)
|
||||
res.status(200)
|
||||
res.send('Invitation sent to email')
|
||||
}
|
||||
|
||||
export const postSession = async (req: Request, res: Response) => {
|
||||
try {
|
||||
await handlePostSession(req, res)
|
||||
} catch (e) {
|
||||
console.error('Error in request new session for existing user', e)
|
||||
res.send('Request session error')
|
||||
res.status(500)
|
||||
throw e
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["es6", "dom"],
|
||||
"lib": ["es2015", "esnext.asynciterable"],
|
||||
"module": "commonjs",
|
||||
"noImplicitReturns": true,
|
||||
"outDir": "lib",
|
||||
|
|
|
@ -107,9 +107,6 @@
|
|||
// Warns if function overloads could be unified into a single function with optional or rest parameters.
|
||||
"unified-signatures": {"severity": "warning"},
|
||||
|
||||
// Warns if code has an import or variable that is unused.
|
||||
"no-unused-variable": {"severity": "warning"},
|
||||
|
||||
// Prefer const for values that will not change. This better documents code.
|
||||
"prefer-const": {"severity": "warning"},
|
||||
|
||||
|
|
|
@ -10,4 +10,4 @@
|
|||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"extends": [
|
||||
"tslint:recommended",
|
||||
"tslint:recommended"
|
||||
],
|
||||
"linterOptions": {
|
||||
"exclude": [
|
||||
|
|
Loading…
Reference in New Issue