Merge Complete
This commit is contained in:
1 parent
482ef7a81a
commit
dabe23d505
6483 files changed
No files matched your search
@@ -0,0 +1,131 @@
|
||||
import http from 'http'
|
||||
import { ApolloServer, makeExecutableSchema } from 'apollo-server-express'
|
||||
import { applyMiddleware as applyGraphQLMiddleware } from 'graphql-middleware'
|
||||
import { moduleAuth } from './middleware'
|
||||
import logger from './logger'
|
||||
|
||||
/**
|
||||
*
|
||||
* @description Creates an Apollo Server. Setup based on `vue-cli-plugin-apollo`.
|
||||
* @param {Object} app Express application
|
||||
* @param {Object} options Apollo options
|
||||
* @returns {Object} HTTP Server
|
||||
*/
|
||||
export default function createApolloServer(
|
||||
app,
|
||||
{
|
||||
// Main options
|
||||
graphqlEndpoint = '',
|
||||
typeDefs = {},
|
||||
resolvers = {},
|
||||
schemaDirectives = {},
|
||||
directiveResolvers = {},
|
||||
graphqlMiddlewares = [],
|
||||
dataSources = () => ({}),
|
||||
context = () => ({}),
|
||||
// Subscriptions
|
||||
subscriptionsEndpoint = '',
|
||||
wsMiddlewares = [],
|
||||
// Mocks
|
||||
mocks,
|
||||
// Apollo Engine
|
||||
engineKey = '',
|
||||
// HTTP options
|
||||
cors = true,
|
||||
timeout = 120000,
|
||||
// Extra options for Apollo Server
|
||||
apolloServerOptions = {},
|
||||
}
|
||||
) {
|
||||
const schema = makeExecutableSchema({
|
||||
typeDefs,
|
||||
resolvers,
|
||||
schemaDirectives,
|
||||
directiveResolvers,
|
||||
resolverValidationOptions: {
|
||||
requireResolversForResolveType: false,
|
||||
},
|
||||
})
|
||||
|
||||
// Apollo server options
|
||||
const options = {
|
||||
...apolloServerOptions,
|
||||
schema: applyGraphQLMiddleware(schema, ...graphqlMiddlewares),
|
||||
tracing: true,
|
||||
cacheControl: true,
|
||||
introspection: true,
|
||||
playground: true,
|
||||
engine: engineKey ? { apiKey: engineKey } : false,
|
||||
dataSources,
|
||||
// Resolvers context in POST requests
|
||||
context: async ({ req, connection }) => {
|
||||
let contextData
|
||||
try {
|
||||
if (connection) {
|
||||
contextData = { ...connection.context }
|
||||
} else {
|
||||
contextData = await context({ req, request: req })
|
||||
}
|
||||
} catch (err) {
|
||||
logger.error(err)
|
||||
throw err
|
||||
}
|
||||
|
||||
return contextData
|
||||
},
|
||||
// Resolvers context in WebSocket requests
|
||||
subscriptions: {
|
||||
path: subscriptionsEndpoint,
|
||||
onConnect: async (connection, websocket) => {
|
||||
const { authorization, userid } = connection
|
||||
|
||||
let contextData = {}
|
||||
try {
|
||||
// Simulate `req` object for auth
|
||||
const req = { headers: { authorization, userid } }
|
||||
|
||||
// Call all middlewares in order and modify `req`
|
||||
await new Promise((resolve, reject) =>
|
||||
wsMiddlewares.reduceRight(
|
||||
(acc, m) => err => (err ? reject(err) : m(req, null, acc)),
|
||||
err => (err ? reject(err) : resolve())
|
||||
)()
|
||||
)
|
||||
|
||||
contextData = await context({
|
||||
connection,
|
||||
websocket,
|
||||
request: req,
|
||||
req,
|
||||
})
|
||||
} catch (err) {
|
||||
logger.error(err)
|
||||
}
|
||||
|
||||
return contextData
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// Apollo Server
|
||||
const server = new ApolloServer(options)
|
||||
|
||||
// Express middleware
|
||||
server.applyMiddleware({
|
||||
moduleAuth,
|
||||
app,
|
||||
cors,
|
||||
path: graphqlEndpoint,
|
||||
// gui: {
|
||||
// endpoint: graphqlEndpoint,
|
||||
// subscriptionEndpoint: graphqlSubscriptionsPath,
|
||||
// },
|
||||
})
|
||||
|
||||
// Create HTTP server and add subscriptions
|
||||
const httpServer = http.createServer(app)
|
||||
httpServer.setTimeout(timeout)
|
||||
server.installSubscriptionHandlers(httpServer)
|
||||
|
||||
return httpServer
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import { ApolloError } from 'apollo-server-express'
|
||||
import { inspect } from 'util'
|
||||
import logger from '../logger'
|
||||
|
||||
export {
|
||||
ApolloError,
|
||||
AuthenticationError,
|
||||
ForbiddenError,
|
||||
SyntaxError,
|
||||
UserInputError,
|
||||
ValidationError,
|
||||
} from 'apollo-server-express'
|
||||
|
||||
export const formatError = (error) => {
|
||||
// This can be used to send errors to third
|
||||
// party services like Sentry or Stackdriver
|
||||
logger.info('formatError')
|
||||
logger.error(JSON.parse(JSON.stringify(inspect(error))))
|
||||
const originalError = searchOriginalError(error)
|
||||
logger.error('originalError')
|
||||
logger.error(originalError)
|
||||
const { message, code } = originalError
|
||||
return { message, code}
|
||||
}
|
||||
|
||||
const searchOriginalError = (error) => {
|
||||
if (error.originalError) {
|
||||
logger.error('Original Error')
|
||||
logger.error(error.originalError)
|
||||
return error.originalError
|
||||
}
|
||||
if (error.errors) {
|
||||
logger.error('Errors')
|
||||
logger.error(JSON.parse(JSON.stringify(inspect(error.errors))))
|
||||
return error.errors.map(searchOriginalError)[0]
|
||||
}
|
||||
logger.error('searchOriginalErrors')
|
||||
logger.error(JSON.parse(JSON.stringify(inspect(error))))
|
||||
return error;
|
||||
}
|
||||
|
||||
// Define custom Apollo errors here
|
||||
export class ExternalServiceError extends ApolloError {
|
||||
constructor(message) {
|
||||
super(message, 'EXTERNAL_SERVICE_UNAVAILABLE')
|
||||
|
||||
Object.defineProperty(this, 'name', { value: this.constructor.name })
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"code": 401,
|
||||
"message": "Wait, you're not supposed to be here, go through the gate as everyone else"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import Corporate from './sendgrid/corporate'
|
||||
import Master from './sendgrid/master'
|
||||
import Teams from './sendgrid/teams'
|
||||
|
||||
export const resolvers = {
|
||||
Mutation: {
|
||||
Corporate_NewsletterSignup: (parent, arg, ctx, info) => Corporate.Corporate_NewsletterSignup(parent, arg, ctx, info),
|
||||
Corporate_NewsletterSignupVerify: (parent, arg, ctx, info) => Corporate.Corporate_NewsletterSignupVerify(parent, arg, ctx, info),
|
||||
Corporate_Contact: (parent, arg, ctx, info) => Corporate.Corporate_Contact(parent, arg, ctx, info),
|
||||
Master_NewsletterSignup: (parent, arg, ctx, info) => Master.Master_NewsletterSignup(parent, arg, ctx, info),
|
||||
Master_NewsletterSignupVerify: (parent, arg, ctx, info) => Master.Master_NewsletterSignupVerify(parent, arg, ctx, info),
|
||||
Master_Feedback: (parent, arg, ctx, info) => Master.Master_Feedback(parent, arg, ctx, info),
|
||||
Teams_SendTeamMemberInvite: (parent, arg, ctx, info) => Teams.Teams_SendTeamMemberInvite(parent, arg, ctx, info),
|
||||
Teams_VerifyTeamMemberInviteToken: (parent, arg, ctx, info) => Teams.Teams_VerifyTeamMemberInviteToken(parent, arg, ctx, info),
|
||||
Teams_SendTeamCreateConfirmation: (parent, arg, ctx, info) => Teams.Teams_SendTeamCreateConfirmation(parent, arg, ctx, info)
|
||||
}
|
||||
}
|
||||
+221
@@ -0,0 +1,221 @@
|
||||
import sgMail from '@sendgrid/mail'
|
||||
import axios from 'axios'
|
||||
import jwt from 'jsonwebtoken'
|
||||
import { ApolloError } from 'apollo-server-express'
|
||||
|
||||
import logger from '../../../../logger'
|
||||
|
||||
const API_KEY = process.env.SG_APIKEY
|
||||
const API_KEY_CAMPAIGN = process.env.SG_APIKEY_CAMPAIGN
|
||||
const CORPORATE_EMAIL = process.env.CORPORATE_EMAIL
|
||||
|
||||
const origin = process.env.SG_CORPORATE_ORIGIN
|
||||
|
||||
export default {
|
||||
async Corporate_NewsletterSignup(parent, { email }, ctx, info) {
|
||||
logger.info('Corporate_NewsletterSignup params email:')
|
||||
logger.info(email)
|
||||
const token = jwt.sign({ email: email }, API_KEY, { expiresIn: '1d' })
|
||||
const params = '/email-verification.shtml?token='
|
||||
|
||||
const data = JSON.stringify({
|
||||
"personalizations": [
|
||||
{
|
||||
"to": [
|
||||
{
|
||||
"email": email
|
||||
}
|
||||
],
|
||||
dynamic_template_data: {
|
||||
"aaverifylink": origin + params + token,
|
||||
"subject": 'VERIFY YOUR INTEREST in the Superalgos project'
|
||||
},
|
||||
"subject": 'VERIFY YOUR INTEREST in the Superalgos project'
|
||||
}
|
||||
],
|
||||
"from": {
|
||||
"email": "feedback@superalgos.org",
|
||||
"name": "Superalgos Project Team"
|
||||
},
|
||||
"template_id": process.env.SG_CORPORATE_SIGNUP_EMAILID
|
||||
})
|
||||
|
||||
const sendVerify = axios({
|
||||
method: 'post',
|
||||
url: 'https://api.sendgrid.com/v3/mail/send',
|
||||
data: data,
|
||||
headers:{
|
||||
'content-type': 'application/json',
|
||||
'authorization': 'Bearer ' + API_KEY
|
||||
}
|
||||
})
|
||||
.then(function (response) {
|
||||
logger.info('Sendgrid sendVerify response:')
|
||||
logger.info(response)
|
||||
if (response.status >= 200 && response.status < 300) {
|
||||
return 'SUCCESS'
|
||||
} else {
|
||||
throw response.data.errors[0].message
|
||||
}
|
||||
})
|
||||
.catch(function (error) {
|
||||
logger.error('Sendgrid sendVerify Error:')
|
||||
logger.error(error)
|
||||
throw new ApolloError(`Sendgrid sendVerify Error: ${error.response.data.errors[0].message}`, 404)
|
||||
})
|
||||
return sendVerify
|
||||
},
|
||||
|
||||
async Corporate_NewsletterSignupVerify(parent, { token }, ctx, info){
|
||||
let verifiedToken
|
||||
try {
|
||||
verifiedToken = jwt.verify(token, API_KEY, {maxAge: '1d'})
|
||||
} catch(err) {
|
||||
logger.error('Sendgrid verifiedToken Error:')
|
||||
logger.error(err)
|
||||
if (err.name === 'TokenExpiredError'){
|
||||
throw new ApolloError('Error: Token Expired. Please resubmit email address.', 400)
|
||||
} else {
|
||||
throw new ApolloError(`Error: ${err.message}`, 400)
|
||||
}
|
||||
}
|
||||
logger.info('Sendgrid verifySignup verifiedToken: ')
|
||||
logger.info(verifiedToken)
|
||||
|
||||
const email = verifiedToken.email
|
||||
|
||||
const subscribe = axios({
|
||||
method: 'post',
|
||||
url: 'https://api.sendgrid.com/v3/contactdb/recipients',
|
||||
data: [{"email": email}],
|
||||
headers:{
|
||||
'content-type': 'application/json',
|
||||
'authorization': 'Bearer ' + API_KEY_CAMPAIGN
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
logger.info('Sendgrid verifySignup subscribe: ')
|
||||
logger.info(response)
|
||||
const recipients = response.data.persisted_recipients
|
||||
|
||||
if (recipients.length > 0 ){
|
||||
const addToList = axios({
|
||||
method: 'post',
|
||||
url: 'https://api.sendgrid.com/v3/contactdb/lists/4068018/recipients/' + recipients[0],
|
||||
headers:{
|
||||
'content-type': 'application/json',
|
||||
'authorization': 'Bearer ' + API_KEY_CAMPAIGN
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
logger.info('Sendgrid verifySignup addToList: ')
|
||||
logger.info(response)
|
||||
if (response.status >= 200 && response.status < 300) {
|
||||
return 'SUCCESS'
|
||||
} else {
|
||||
throw response.data.errors[0].message
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
logger.error('Sendgrid verifySignUp subscribe Error:')
|
||||
logger.error(error)
|
||||
throw `Email SignUp Error: ${error}`
|
||||
})
|
||||
return addToList
|
||||
} else{
|
||||
return response.data.errors[0].message
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
return response
|
||||
})
|
||||
.catch(error => {
|
||||
logger.error('Sendgrid verifySubscribe Error:')
|
||||
logger.error(error)
|
||||
throw new ApolloError(`Sendgrid verifySubscribe Error: ${error.response.data.errors[0].message}`, 404)
|
||||
})
|
||||
return subscribe
|
||||
},
|
||||
|
||||
async Corporate_Contact(parent, { email, name, message, recaptcha }, ctx, info) {
|
||||
logger.info(`Corporate_Contact: ${email} | ${name} | ${message} | ${recaptcha}`)
|
||||
const data = JSON.stringify({
|
||||
"personalizations": [
|
||||
{
|
||||
"to": [
|
||||
{
|
||||
"email": CORPORATE_EMAIL
|
||||
}
|
||||
],
|
||||
dynamic_template_data: {
|
||||
"aacontactname": name,
|
||||
"aacontactemail": email,
|
||||
"aacontactbody": message,
|
||||
"subject": `Superalgos Project Site Contact - Message from ${name}`
|
||||
},
|
||||
"subject": `Superalgos Project Site Contact - Message from ${name}`
|
||||
}
|
||||
],
|
||||
"from": {
|
||||
"email": "feedback@superalgos.org",
|
||||
"name": "Superalgos Project Team"
|
||||
},
|
||||
"reply_to": {
|
||||
"email": email,
|
||||
"name": name
|
||||
},
|
||||
"template_id": process.env.SG_CORPORATE_CONTACT_EMAILID
|
||||
})
|
||||
|
||||
const checkCaptcha = axios({
|
||||
method: 'post',
|
||||
url: 'https://www.google.com/recaptcha/api/siteverify',
|
||||
params: {
|
||||
secret: process.env.RECAPTCHA,
|
||||
response: recaptcha
|
||||
}
|
||||
})
|
||||
.then(function (response) {
|
||||
// logger.info(response)
|
||||
if (response.status >= 200 && response.status < 300 && response.data.success) {
|
||||
return axios({
|
||||
method: 'post',
|
||||
url: 'https://api.sendgrid.com/v3/mail/send',
|
||||
data: data,
|
||||
headers:{
|
||||
'content-type': 'application/json',
|
||||
'authorization': 'Bearer ' + API_KEY
|
||||
}
|
||||
})
|
||||
.then(function (response) {
|
||||
// logger.info('Sendgrid Contact response: ')
|
||||
// logger.info(response)
|
||||
if (response.status >= 200 && response.status < 300) {
|
||||
logger.info('Sendgrid Contact email sent')
|
||||
return `Superalgos Project Contact email sent`
|
||||
} else {
|
||||
throw response.data.errors[0].message
|
||||
}
|
||||
})
|
||||
.catch(function (error) {
|
||||
logger.error(`sendgrid Error: ${JSON.stringify(error)}`)
|
||||
throw `Superalgos Project Contact email send error: ${error.response.data.errors[0].message}`
|
||||
})
|
||||
}else{
|
||||
logger.info('Superalgos Project Contact recaptcha error')
|
||||
logger.info(response.data)
|
||||
throw { response: { data: JSON.stringify(response.data) } }
|
||||
}
|
||||
})
|
||||
.then(function(response){
|
||||
return response
|
||||
})
|
||||
.catch(function (error) {
|
||||
logger.error('Sendgrid Superalgos Project Contact RECAPTCHA Error:')
|
||||
logger.error(error)
|
||||
throw new ApolloError(`Sendgrid Superalgos Project Contact RECAPTCHA Error: ${error.response.data}`, 404)
|
||||
})
|
||||
|
||||
return checkCaptcha
|
||||
}
|
||||
}
|
||||
+219
@@ -0,0 +1,219 @@
|
||||
import sgMail from '@sendgrid/mail'
|
||||
import axios from 'axios'
|
||||
import jwt from 'jsonwebtoken'
|
||||
import { ApolloError } from 'apollo-server-express'
|
||||
|
||||
import logger from '../../../../logger'
|
||||
|
||||
const API_KEY = process.env.SG_APIKEY
|
||||
const API_KEY_CAMPAIGN = process.env.SG_APIKEY_CAMPAIGN
|
||||
|
||||
const origin = process.env.SG_PLATFORM_ORIGIN
|
||||
|
||||
export default {
|
||||
async Master_NewsletterSignup(parent, { email }, ctx, info) {
|
||||
logger.info('Master_NewsletterSignup params email:')
|
||||
logger.info(email)
|
||||
const token = jwt.sign({ email: email }, API_KEY, { expiresIn: '1d' })
|
||||
const params = '/email-verification?token='
|
||||
|
||||
const data = JSON.stringify({
|
||||
"personalizations": [
|
||||
{
|
||||
"to": [
|
||||
{
|
||||
"email": email
|
||||
}
|
||||
],
|
||||
dynamic_template_data: {
|
||||
"aaverifylink": origin + params + token,
|
||||
"subject": 'VERIFY YOUR INTEREST in the Superalgos Project'
|
||||
},
|
||||
"subject": 'VERIFY YOUR INTEREST in the Superalgos Project'
|
||||
}
|
||||
],
|
||||
"from": {
|
||||
"email": "feedback@superalgos.org",
|
||||
"name": "Superalgos Project Team"
|
||||
},
|
||||
"reply_to": {
|
||||
"email": "feedback@superalgos.org",
|
||||
"name": "Superalgos Project Team"
|
||||
},
|
||||
"template_id": process.env.SG_MASTER_SIGNUP_EMAILID
|
||||
})
|
||||
|
||||
const sendVerify = axios({
|
||||
method: 'post',
|
||||
url: 'https://api.sendgrid.com/v3/mail/send',
|
||||
data: data,
|
||||
headers:{
|
||||
'content-type': 'application/json',
|
||||
'authorization': 'Bearer ' + API_KEY
|
||||
}
|
||||
})
|
||||
.then(function (response) {
|
||||
logger.info('Sendgrid Master SendVerify response:')
|
||||
logger.info (response)
|
||||
if (response.status >= 200 && response.status < 300) {
|
||||
return 'SUCCESS'
|
||||
} else {
|
||||
throw response.data.errors[0].message
|
||||
}
|
||||
})
|
||||
.catch(function (error) {
|
||||
logger.error('Sendgrid Master SendVerify Error:')
|
||||
logger.error(error)
|
||||
throw new ApolloError(`Sendgrid Master SendVerify Error: ${error.response.data.errors[0].message}`, 404)
|
||||
})
|
||||
return sendVerify
|
||||
},
|
||||
async Master_NewsletterSignupVerify(parent, { token }, ctx, info){
|
||||
let verifiedToken
|
||||
try {
|
||||
verifiedToken = jwt.verify(token, API_KEY, {maxAge: '1d'})
|
||||
} catch(err) {
|
||||
logger.error('Sendgrid Master verifiedToken Error:')
|
||||
logger.error(err)
|
||||
if (err.name === 'TokenExpiredError'){
|
||||
throw new ApolloError('Error: Token Expired. Please resubmit email address.', 400)
|
||||
} else {
|
||||
throw new ApolloError(`Error: ${err.message}`, 400)
|
||||
}
|
||||
}
|
||||
logger.info('Sendgrid Master verifySignup verifiedToken: ')
|
||||
logger.info(verifiedToken)
|
||||
|
||||
const email = verifiedToken.email
|
||||
|
||||
const subscribe = axios({
|
||||
method: 'post',
|
||||
url: 'https://api.sendgrid.com/v3/contactdb/recipients',
|
||||
data: [{"email": email}],
|
||||
headers:{
|
||||
'content-type': 'application/json',
|
||||
'authorization': 'Bearer ' + API_KEY_CAMPAIGN
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
logger.info('Sendgrid Master verifySignup subscribe: ')
|
||||
logger.info(response)
|
||||
const recipients = response.data.persisted_recipients
|
||||
|
||||
if (recipients.length > 0 ){
|
||||
const addToList = axios({
|
||||
method: 'post',
|
||||
url: 'https://api.sendgrid.com/v3/contactdb/lists/4068018/recipients/' + recipients[0],
|
||||
headers:{
|
||||
'content-type': 'application/json',
|
||||
'authorization': 'Bearer ' + API_KEY_CAMPAIGN
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
logger.info('Sendgrid Master verifySignup addToList: ')
|
||||
logger.info(response)
|
||||
if (response.status >= 200 && response.status < 300) {
|
||||
return 'SUCCESS'
|
||||
} else {
|
||||
throw response.data.errors[0].message
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
logger.error('Sendgrid Master verifySignUp subscribe Error:')
|
||||
logger.error(error)
|
||||
throw `Email SignUp Error: ${error}`
|
||||
})
|
||||
return addToList
|
||||
} else{
|
||||
return response.data.errors[0].message
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
return response
|
||||
})
|
||||
.catch(error => {
|
||||
logger.error('Sendgrid Master verifySubscribe Error:')
|
||||
logger.error(error)
|
||||
throw new ApolloError(`Sendgrid Master verifySubscribe Error: ${error.response.data.errors[0].message}`, 404)
|
||||
})
|
||||
return subscribe
|
||||
},
|
||||
async Master_Feedback(parent, { email, subject, message, recaptcha }, ctx, info) {
|
||||
const toEmail = 'feedback@superalgos.org'
|
||||
|
||||
const data = JSON.stringify({
|
||||
"personalizations": [
|
||||
{
|
||||
"to": [
|
||||
{
|
||||
"email": toEmail
|
||||
}
|
||||
],
|
||||
dynamic_template_data: {
|
||||
"aacontactname": name,
|
||||
"aacontactemail": email,
|
||||
"aacontactbody": message
|
||||
},
|
||||
"subject": `Superalgos Platform App Feedback - Message from ${name}`
|
||||
}
|
||||
],
|
||||
"from": {
|
||||
"email": email,
|
||||
"name": name
|
||||
},
|
||||
"reply_to": {
|
||||
"email": email,
|
||||
"name": name
|
||||
},
|
||||
"template_id": process.env.SG_MASTER_FEEDBACK_EMAILID
|
||||
})
|
||||
|
||||
const checkCaptcha = axios({
|
||||
method: 'post',
|
||||
url: 'https://www.google.com/recaptcha/api/siteverify',
|
||||
params: {
|
||||
secret: process.env.RECAPTCHA,
|
||||
response: recaptcha
|
||||
}
|
||||
})
|
||||
.then(function (response) {
|
||||
logger.info(response.data)
|
||||
if (response.status >= 200 && response.status < 300 && response.data.success) {
|
||||
return axios({
|
||||
method: 'post',
|
||||
url: 'https://api.sendgrid.com/v3/mail/send',
|
||||
data: data,
|
||||
headers:{
|
||||
'content-type': 'application/json',
|
||||
'authorization': 'Bearer ' + API_KEY
|
||||
}
|
||||
})
|
||||
.then(function (response) {
|
||||
logger.info('Platform Feedback response: ')
|
||||
logger.info(response)
|
||||
if (response.status >= 200 && response.status < 300) {
|
||||
return `Platform Feedback email sent`
|
||||
} else {
|
||||
throw response.data.errors[0].message
|
||||
}
|
||||
})
|
||||
.catch(function (error) {
|
||||
logger.error(`sendgrid Error: ${JSON.stringify(error)}`)
|
||||
throw `Platform Feedback email send error: ${error.response.data.errors[0].message}`
|
||||
})
|
||||
}else{
|
||||
throw response.data
|
||||
}
|
||||
})
|
||||
.then(function(response){
|
||||
return response
|
||||
})
|
||||
.catch(function (error) {
|
||||
logger.error('Platform Feedback RECAPTCHA Error:')
|
||||
logger.error(error)
|
||||
throw new ApolloError(`Platform Feedback RECAPTCHA Error: ${error.response.data.errors[0].message}`, 404)
|
||||
})
|
||||
|
||||
return checkCaptcha
|
||||
}
|
||||
}
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
import sgMail from '@sendgrid/mail'
|
||||
import axios from 'axios'
|
||||
import jwt from 'jsonwebtoken'
|
||||
import { ApolloError } from 'apollo-server-express'
|
||||
|
||||
import logger from '../../../../logger'
|
||||
|
||||
const API_KEY = process.env.SG_APIKEY
|
||||
const API_KEY_CAMPAIGN = process.env.SG_APIKEY_CAMPAIGN
|
||||
|
||||
const origin = process.env.SG_PLATFORM_ORIGIN
|
||||
|
||||
export default {
|
||||
async Teams_SendTeamMemberInvite(parent, { email, teamName }, ctx, info) {
|
||||
logger.info('Teams_NewsletterSignup params email:')
|
||||
logger.info(email)
|
||||
const token = jwt.sign({ email: email }, API_KEY, { expiresIn: '1d' })
|
||||
const params = '/email-verification?token='
|
||||
|
||||
const data = JSON.stringify({
|
||||
"personalizations": [
|
||||
{
|
||||
"to": [
|
||||
{
|
||||
"email": email
|
||||
}
|
||||
],
|
||||
dynamic_template_data: {
|
||||
"aateaminvitelink": origin + params + token,
|
||||
"aateamname": teamName,
|
||||
"subject": "INVITATION: Join team " + teamName
|
||||
},
|
||||
"subject": "INVITATION: Join team " + teamName
|
||||
}
|
||||
],
|
||||
"from": {
|
||||
"email": "noreply@superalgos.org",
|
||||
"name": "Superalgos Project Teams"
|
||||
},
|
||||
"reply_to": {
|
||||
"email": "feedback@superalgos.org",
|
||||
"name": "Superalgos Project Teams"
|
||||
},
|
||||
"template_id": process.env.SG_TEAMS_MEMBER_INVITE_EMAILID
|
||||
})
|
||||
|
||||
let sendVerify = axios({
|
||||
method: 'post',
|
||||
url: 'https://api.sendgrid.com/v3/mail/send',
|
||||
data: data,
|
||||
headers:{
|
||||
'content-type': 'application/json',
|
||||
'authorization': 'Bearer ' + API_KEY
|
||||
}
|
||||
})
|
||||
.then(function (response) {
|
||||
if (response.status >= 200 && response.status < 300) {
|
||||
return 'Success'
|
||||
} else {
|
||||
throw response.data.errors[0].message
|
||||
}
|
||||
})
|
||||
.catch(function (error) {
|
||||
throw new ApolloError (`Send Team Invite Verification Error: - ${error.status}-${error.response.data.errors[0].message}`, 404)
|
||||
})
|
||||
return sendVerify
|
||||
},
|
||||
|
||||
async Teams_VerifyTeamMemberInviteToken(parent, { email, teamName }, ctx, info) {
|
||||
let verifiedToken
|
||||
try {
|
||||
verifiedToken = await jwt.verify(token, API_KEY, {maxAge: '7d'})
|
||||
} catch(err) {
|
||||
if (err.name === "TokenExpiredError"){
|
||||
throw new ApolloError('Team Invite Token Error: Token Expired. Please request new invitation or apply to the team again', 404)
|
||||
} else {
|
||||
throw new ApolloError (`Team Invite Token Error: - ${err.message}`, 404)
|
||||
}
|
||||
}
|
||||
logger.info(`verifyInviteToken: ${verifiedToken}`)
|
||||
return verifiedToken
|
||||
},
|
||||
|
||||
async Teams_SendTeamCreateConfirmation(parent, { email, teamName, botName }, ctx, info){
|
||||
const data = JSON.stringify({
|
||||
"personalizations": [
|
||||
{
|
||||
"to": [
|
||||
{
|
||||
"email": email
|
||||
}
|
||||
],
|
||||
dynamic_template_data: {
|
||||
"aadeveloplink": "https://platform.superalgos.org/index.html",
|
||||
"aateamname": teamName,
|
||||
"aabotname": botName,
|
||||
"subject": "Team " + teamName + " has been created!"
|
||||
},
|
||||
"subject": "Team " + teamName + " has been created!"
|
||||
}
|
||||
],
|
||||
"from": {
|
||||
"email": "noreply@superalgos.org",
|
||||
"name": "Superalgos Project Teams"
|
||||
},
|
||||
"reply_to": {
|
||||
"email": "feedback@superalgos.org",
|
||||
"name": "Superalgos Project Teams"
|
||||
},
|
||||
"template_id": process.env.SG_TEAMS_TEAMCREATE_EMAILID
|
||||
})
|
||||
|
||||
let sendTeamCreation = axios({
|
||||
method: 'post',
|
||||
url: 'https://api.sendgrid.com/v3/mail/send',
|
||||
data: data,
|
||||
headers:{
|
||||
'content-type': 'application/json',
|
||||
'authorization': 'Bearer ' + API_KEY
|
||||
}
|
||||
})
|
||||
.then(function (response) {
|
||||
if (response.status >= 200 && response.status < 300) {
|
||||
return 'Success'
|
||||
} else {
|
||||
throw response.data.errors[0].message
|
||||
}
|
||||
})
|
||||
.catch(function (error) {
|
||||
throw new ApolloError(`Team Creation Confirmation Error: ${error.response.data.errors[0].message}`)
|
||||
})
|
||||
return sendTeamCreation
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import logger from '../../../logger'
|
||||
|
||||
export const resolvers = {
|
||||
Query: {
|
||||
_blank: (parent, arg, ctx, info) => { return '' }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import merge from 'lodash.merge'
|
||||
|
||||
import { resolvers as queryResolvers } from './Query'
|
||||
import { resolvers as mutationResolvers } from './Mutation'
|
||||
|
||||
export const resolvers = merge(queryResolvers, mutationResolvers)
|
||||
@@ -0,0 +1,15 @@
|
||||
type Query {
|
||||
_blank: String
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
Corporate_NewsletterSignup(email: String!): String
|
||||
Corporate_NewsletterSignupVerify(token: String!): String
|
||||
Corporate_Contact(email: String!, name: String, message: String!, recaptcha: String!): String
|
||||
Master_NewsletterSignup(email: String!): String
|
||||
Master_NewsletterSignupVerify(token: String!): String
|
||||
Master_Feedback(email: String!, subject: String!, message: String!, recaptcha: String!): String
|
||||
Teams_SendTeamMemberInvite(email: String!, teamName: String!): String
|
||||
Teams_SendTeamCreateConfirmation(email: String!, teamName: String!, botName: String!): String
|
||||
Teams_VerifyTeamMemberInviteToken(token: String!): String
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
import '@babel/polyfill'
|
||||
require('dotenv').config();
|
||||
import express from 'express'
|
||||
import createApolloServer from './ApolloServer'
|
||||
import { formatError } from './errors'
|
||||
import { makeExecutableSchema } from 'graphql-tools'
|
||||
import { importSchema } from 'graphql-import'
|
||||
|
||||
import { resolvers } from './graphql/resolvers'
|
||||
|
||||
import logger from './logger'
|
||||
|
||||
import wrongPreshared from './errors/notAllowed.json'
|
||||
|
||||
const GRAPHQL_ENDPOINT = '/graphql'
|
||||
const GRAPHQL_SUBSCRIPTIONS = '/graphql'
|
||||
const PORT = process.env.PORT
|
||||
const NODE_ENV = 'development'
|
||||
|
||||
const app = express()
|
||||
|
||||
app.post(GRAPHQL_ENDPOINT, (req, res, next) => {
|
||||
if (req.headers.preshared === process.env.PRESHARED_GATEWAY_KEY) {
|
||||
next();
|
||||
} else {
|
||||
res.send(wrongPreshared);
|
||||
}
|
||||
});
|
||||
|
||||
app.post(GRAPHQL_ENDPOINT)
|
||||
|
||||
const corsOptions = {
|
||||
"origin": "*",
|
||||
"methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
|
||||
"preflightContinue": false,
|
||||
"optionsSuccessStatus": 204
|
||||
}
|
||||
|
||||
const options = {
|
||||
port: PORT,
|
||||
cors: corsOptions,
|
||||
endpoint: '/graphql',
|
||||
subscriptions: '/graphql'
|
||||
}
|
||||
|
||||
let server
|
||||
try {
|
||||
server = createApolloServer(app, {
|
||||
graphqlEndpoint: GRAPHQL_ENDPOINT,
|
||||
subscriptionsEndpoint: GRAPHQL_SUBSCRIPTIONS,
|
||||
apolloServerOptions: { formatError },
|
||||
typeDefs: importSchema('src/graphql/schema.graphql'),
|
||||
resolvers,
|
||||
resolverValidationOptions: { requireResolversForResolveType: false },
|
||||
context: req => ({
|
||||
...req ,
|
||||
token: req.headers ? req.headers : undefined,
|
||||
user: req.user ? req.user : undefined,
|
||||
userId: (req.headers && req.headers.userid) ? req.headers.userid : undefined
|
||||
})
|
||||
})
|
||||
} catch (err) {
|
||||
logger.error('Create Apollo Server Error: ')
|
||||
logger.error(err)
|
||||
}
|
||||
|
||||
server.listen({ port: PORT }, () => {
|
||||
logger.info(
|
||||
`🚀 GraphQL Server is running on http://localhost:${PORT}${GRAPHQL_ENDPOINT} in "${NODE_ENV}" mode\n`
|
||||
)
|
||||
})
|
||||
@@ -0,0 +1,41 @@
|
||||
import { createLogger, format, transports } from 'winston'
|
||||
import { inspect } from 'util'
|
||||
|
||||
const { combine, timestamp, simple } = format
|
||||
|
||||
const options = {
|
||||
file: {
|
||||
level: 'info',
|
||||
filename: '../logs/app.log',
|
||||
handleExceptions: true,
|
||||
json: true,
|
||||
maxsize: 5242880, // 5MB
|
||||
maxFiles: 5,
|
||||
colorize: false,
|
||||
timestamp: true
|
||||
},
|
||||
console: {
|
||||
level: 'info',
|
||||
handleExceptions: true,
|
||||
json: false,
|
||||
colorize: true,
|
||||
}
|
||||
}
|
||||
|
||||
const logger = createLogger({
|
||||
level: 'info',
|
||||
format: format.combine(
|
||||
format.colorize(),
|
||||
format.timestamp({ format: 'YY/MM/DD HH:mm' }),
|
||||
format.printf(
|
||||
info => `${info.timestamp} - ${info.level}: ${JSON.parse(JSON.stringify(inspect(info.message)))}`
|
||||
)
|
||||
),
|
||||
transports: [
|
||||
new transports.File(options.file),
|
||||
new transports.Console(options.console)
|
||||
],
|
||||
exitOnError: false // do not exit on handled exceptions
|
||||
})
|
||||
|
||||
export default logger
|
||||
@@ -0,0 +1,3 @@
|
||||
import moduleAuth from './moduleAuth'
|
||||
|
||||
export { moduleAuth }
|
||||
@@ -0,0 +1,13 @@
|
||||
import logger from '../logger'
|
||||
|
||||
export const moduleAuth = async (req, res, next, db) => {
|
||||
if (req.headers.preshared === process.env.PRESHARED_GATEWAY_KEY) {
|
||||
logger.info('Module authenticated')
|
||||
next();
|
||||
} else {
|
||||
logger.error('Module authentication error')
|
||||
res.send(wrongPreshared);
|
||||
}
|
||||
}
|
||||
|
||||
export default moduleAuth
|
||||
@@ -0,0 +1,3 @@
|
||||
import { PubSub } from 'graphql-subscriptions'
|
||||
|
||||
export default new PubSub()
|
||||
Reference in new issue
Block a user