Merge pull request #12 from AdvancedAlgos/develop

Fix createTeam with MasterApp
This commit is contained in:
Barry Low authored and GitHub committed 2018-10-21 15:29:25 -07:00
commit 2f8e8f8959
9 files changed
+113 -216

No files matched your search

+19 -15
View File
@@ -1618,7 +1618,7 @@
},
"apollo-link-error": {
"version": "1.0.9",
"resolved": "http://registry.npmjs.org/apollo-link-error/-/apollo-link-error-1.0.9.tgz",
"resolved": "https://registry.npmjs.org/apollo-link-error/-/apollo-link-error-1.0.9.tgz",
"integrity": "sha512-82qgIH0UC039kcvcFDJkY8GuUOgPFrkYe/0zNFkA0AXvuvL4RHxWb8SWRiPwtP8jKaKEOedyjopfyH84aLiu7Q==",
"requires": {
"apollo-link": "^1.2.2"
@@ -1626,7 +1626,7 @@
},
"apollo-link-ws": {
"version": "1.0.8",
"resolved": "http://registry.npmjs.org/apollo-link-ws/-/apollo-link-ws-1.0.8.tgz",
"resolved": "https://registry.npmjs.org/apollo-link-ws/-/apollo-link-ws-1.0.8.tgz",
"integrity": "sha512-ucuGvr8CBBwCHl/Rbtyuv9Fn0FN5Qoyvy84KHtuMl2Uux2Sq+jt3bUum+pZ+hZntEd9k8M1OjrrXqRJ4PtEpyA==",
"requires": {
"apollo-link": "^1.2.2"
@@ -2042,7 +2042,6 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
"integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
"optional": true,
"requires": {
"tweetnacl": "^0.14.3"
}
@@ -3317,7 +3316,6 @@
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
"integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
"optional": true,
"requires": {
"jsbn": "~0.1.0",
"safer-buffer": "^2.1.0"
@@ -6065,8 +6063,7 @@
"jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
"optional": true
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
},
"jsesc": {
"version": "2.5.1",
@@ -7888,7 +7885,7 @@
},
"jsonwebtoken": {
"version": "8.2.1",
"resolved": "http://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.2.1.tgz",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.2.1.tgz",
"integrity": "sha512-l8rUBr0fqYYwPc8/ZGrue7GiW7vWdZtZqelxo4Sd5lMvuEeCK8/wS54sEo6tJhdZ6hqfutsj6COgC0d1XdbHGw==",
"requires": {
"jws": "^3.1.4",
@@ -9015,11 +9012,20 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz",
"integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=",
"dev": true,
"requires": {
"lodash": "^4.13.1"
}
},
"request-promise-native": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.5.tgz",
"integrity": "sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU=",
"requires": {
"request-promise-core": "1.1.1",
"stealthy-require": "^1.1.0",
"tough-cookie": ">=2.3.3"
}
},
"require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
@@ -9640,9 +9646,9 @@
"dev": true
},
"sshpk": {
"version": "1.14.2",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz",
"integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=",
"version": "1.15.1",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.1.tgz",
"integrity": "sha512-mSdgNUaidk+dRU5MhYtN9zebdzF2iG0cNPWy8HG+W8y+fT1JnSkh0fzzpjOa0L7P8i1Rscz38t0h4gPcKz43xA==",
"requires": {
"asn1": "~0.2.3",
"assert-plus": "^1.0.0",
@@ -9687,8 +9693,7 @@
"stealthy-require": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
"integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
"dev": true
"integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks="
},
"stream-combiner": {
"version": "0.2.2",
@@ -10171,8 +10176,7 @@
"tweetnacl": {
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
"optional": true
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
},
"type-is": {
"version": "1.6.16",
+2
View File
@@ -32,6 +32,8 @@
"lodash.get": "^4.4.2",
"nodemon": "^1.18.4",
"prisma-binding": "^2.1.6",
"request": "^2.88.0",
"request-promise-native": "^1.0.5",
"winston": "^3.1.0"
},
"devDependencies": {
-144
View File
@@ -1,144 +0,0 @@
const _get = require('lodash.get')
const { validateIdToken } = require('./validateIdToken')
const memberLocationOnContext = 'request.user'
const bearerAccessToken = 'request.headers.authorization'
const ctxMember = ctx => _get(ctx, memberLocationOnContext)
const ctxToken = ctx => _get(ctx, bearerAccessToken)
const createMember = async (ctx, idToken, info) => {
console.log('createMember', idToken)
const member = await ctx.db.mutation.upsertMember({
where: {
authId: idToken.sub,
},
create: {
authId: idToken.sub,
alias: idToken.nickname
},
update: {
authId: idToken.sub,
alias: idToken.nickname
}
}, info)
return member
}
const isLoggedIn = async ctx => {
console.log('isLoggedIn 0 : ', ctx.request.headers)
let member = ctxMember(ctx, memberLocationOnContext)
let token = ctxToken(ctx, bearerAccessToken)
let memberToken
console.log('isLoggedIn: ', member, token)
if (!member && token) {
let scheme, credentials
const tokenParts = token.split(' ')
if (tokenParts.length === 2) {
scheme = tokenParts[0]
credentials = tokenParts[1]
}
if (/^Bearer$/i.test(scheme)) {
token = credentials
//verify token
// console.log('isLoggedIn2 : ', token)
try {
memberToken = await validateIdToken(token)
const authId = memberToken.sub
// console.log('isLoggedIn3 : ', await authId, ctx.db.query.member)
exists = await ctx.db.query.member({ where: { authId: authId } })
// console.log('isLoggedIn4 : ', await exists, createMember )
if (!member && exists === null) {
member = await createMember(ctx, memberToken).then(res => {
// console.log('isLoggedIn5 : ', res)
return res
})
return member
}
return member
} catch (err) {
memberToken = false
}
}
}
// console.log('isLoggedIn5 : ', await member)
if (!member) {
throw new Error(`Not logged in`)
}
return member
}
const isRequestingMemberAlsoOwner = ({ ctx, memberId, type, typeId }) =>
ctx.db.exists[type]({ slug: typeId, owner: memberId })
const isRequestingMember = ({ ctx, memberId }) => ctx.db.exists.Member({ authId: memberId })
const directiveResolvers = {
isAuthenticated: async (next, source, args, ctx) => {
let result = await isLoggedIn(ctx)
console.log('directive isAuthenticated: ', result)
return next(result)
},
hasRole: (next, source, { roles }, ctx) => {
const { role } = isLoggedIn(ctx)
console.log('directive hasRole: ', role)
if (roles.includes(role)) {
return next()
}
throw new Error(`Unauthorized, incorrect role`)
},
isOwner: async (next, source, { type }, ctx) => {
console.log('directive isOwner: ', source, type, ctx)
const { slug: typeId } =
source && source.id
? source
: ctx.request.body.variables ? ctx.request.body.variables : { id: null }
const user = await isLoggedIn(ctx)
// console.log('directive isOwner 0: ', typeId, user.sub)
const memberId = user.sub
const isOwner =
type === `Member`
? memberId === typeId
: await isRequestingMemberAlsoOwner({ ctx, memberId, type, typeId })
// console.log('directive isOwner 1: ', source, isOwner, type, typeId, memberId)
if (isOwner) {
return next()
}
throw new Error(`Unauthorized, must be owner`)
},
isOwnerOrHasRole: async (next, source, { roles, type }, ctx, ...p) => {
const { authId: memberId } = await isLoggedIn(ctx)
console.log('directive isOwnerOrHasRole 1: ', memberId, roles, type)
if(memberId === undefined && role=== undefined) throw new Error(`Not logged in`)
if (roles.includes(role)) {
return next()
}
const { authId: typeId } = ctx.request.body.variables
const isOwner = await isRequestingMemberAlsoOwner({
ctx,
memberId,
type,
typeId
})
console.log('directive isOwnerOrHasRole 2: ', typeId, memberId, role, isOwner)
if (isOwner) {
return next()
}
const hasRole = await isRequestingMember({
ctx,
memberId,
type,
typeId
})
if(hasRole){
return next()
}
throw new Error(`Unauthorized, not owner or incorrect role`)
}
}
module.exports = { directiveResolvers }
+2 -9
View File
@@ -12,7 +12,7 @@ const ctxMember = ctx => _get(ctx, memberLocationOnContext)
const ctxToken = ctx => _get(ctx, bearerAccessToken)
const createMember = async (ctx, idToken, info) => {
logger.info('createMember', idToken)
logger.info(`createMember: ${idToken}`)
const member = await ctx.db.mutation.upsertMember({
where: {
authId: idToken.sub,
@@ -30,7 +30,7 @@ const createMember = async (ctx, idToken, info) => {
}
const isLoggedIn = async ctx => {
logger.info('isLoggedIn 0 : ', ctx.request.headers)
logger.info(`isLoggedIn 0: ${JSON.stringify(ctx.request.headers)}`)
let member = ctxMember(ctx, memberLocationOnContext)
let token = ctxToken(ctx, bearerAccessToken)
let memberToken
@@ -46,16 +46,12 @@ const isLoggedIn = async ctx => {
if (/^Bearer$/i.test(scheme)) {
token = credentials
//verify token
// console.log('isLoggedIn2 : ', token)
try {
memberToken = await validateIdToken(token)
const authId = memberToken.sub
// console.log('isLoggedIn3 : ', await authId, ctx.db.query.member)
exists = await ctx.db.query.member({ where: { authId: authId } })
// console.log('isLoggedIn4 : ', await exists, createMember )
if (!member && exists === null) {
member = await createMember(ctx, memberToken).then(res => {
// console.log('isLoggedIn5 : ', res)
return res
})
@@ -67,7 +63,6 @@ const isLoggedIn = async ctx => {
}
}
}
// console.log('isLoggedIn5 : ', await member)
if (!member) {
throw new AuthenticationError('Access token is missing or expired')
}
@@ -113,13 +108,11 @@ export const directiveResolvers = {
? source
: ctx.request.body.variables ? ctx.request.body.variables : { id: null }
const user = await isLoggedIn(ctx)
// console.log('directive isOwner 0: ', typeId, user.sub)
const memberId = user.sub
const isOwner =
type === `Member`
? memberId === typeId
: await isRequestingMemberAlsoOwner({ ctx, memberId, type, typeId })
// console.log('directive isOwner 1: ', source, isOwner, type, typeId, memberId)
if (isOwner) {
return next()
}
+5 -4
View File
@@ -1,9 +1,11 @@
var jwt = require('jsonwebtoken')
var axios = require('axios')
import { logger } from '../logger'
const sendTeamMemberInvite = function(email, team) {
const dev = process.env.NODE_ENV === 'development' ? true : false
console.log('sendTeamMemberInvite', email, team)
logger.info(`sendTeamMemberInvite email|team: ${email} | ${team}`)
const API_KEY = process.env.SG_APIKEY
const token = jwt.sign({ email: email, team: team.slug }, API_KEY, { expiresIn: '7d' })
let origin = 'https://teams.advancedalgos.net'
@@ -69,7 +71,7 @@ const sendTeamMemberInvite = function(email, team) {
const sendTeamCreateConfirmation = function(email, teamName, botName) {
const dev = process.env.NODE_ENV === 'development' ? true : false
console.log('sendTeamMemberInvite', email, teamName, botName)
logger.info(`sendTeamCreateConfirmation email|teamName|botName: ${email} | ${teamName} | ${botName}`)
const API_KEY = process.env.SG_APIKEY
let origin = 'https://teams.advancedalgos.net'
if (dev){
@@ -144,8 +146,7 @@ const verifyInviteToken = async function(token) {
throw new Error (`Error: Token error - ${err.message}`)
}
}
console.log('verifyInviteToken', verifiedToken)
logger.info(`verifyInviteToken: ${verifiedToken}`)
return verifiedToken
}
+80 -39
View File
@@ -155,55 +155,57 @@ const resolvers = {
return team
},
async createTeam(parent, { name, slug, botName, botSlug }, ctx, info) {
console.log('createTeam ctx:', ctx.request.user)
logger.info(ctx.request.user, 'createTeam ctx.request.user:')
const authId = ctx.request.user.sub
const encodedAuthId = encodeURI(authId)
const encodedURL = `https://users-api.advancedalgos.net/graphql?query=%7B%0A%20%20userByAuthId(authId%3A%20"${encodedAuthId}")%7B%0A%20%20%20%20id%0A%09%09email%0A%20%20%20%20alias%0A%20%20%7D%0A%7D`
const encodedURL = `https://users-api.advancedalgos.net/graphql?query=%7B%0A%20%20userByAuthId(authId:%20%22${authId}%22)%20%7B%0A%20%20%20%20id%0A%20%20%20%20email%0A%20%20%20%20alias%0A%20%20%7D%0A%7D%0A`
const decodedURL = decodeURI(encodedURL)
logger.info('createTeam URLs: ', encodedURL, decodedURL)
const getUserModuleUser = await axios.get(encodedURL)
.then((result) => {
logger.info('getUserModuleUser axios:', result)
return result
})
.catch(err =>{
logger.debug('getUserModuleUser err:', err)
})
return getUser(authId)
.then(async result => {
logger.info('axios:')
logger.info(result)
logger.info('getUserModuleUser:', await getUserModuleUser)
const alias = await getUserModuleUser.data.data.userByAuthId.alias
const email = getUserModuleUser.data.data.userByAuthId.email
const avatar = 'https://algobotcommstorage.blob.core.windows.net/aateammodule/aa-avatar-default.png'
const banner = 'https://algobotcommstorage.blob.core.windows.net/aateammodule/aa-banner-default.png'
const alias = result.data.users_UserByAuthId.alias
const email = result.data.users_UserByAuthId.email
const avatar = 'https://aadevelop.blob.core.windows.net/module-teams/module-default/aa-avatar-default.png'
const banner = 'https://aadevelop.blob.core.windows.net/module-teams/module-default/aa-banner-default.png'
const createTeamUrl = encodeURI(`${slug}/${name}/${alias}/${botSlug}/${authId}`)
const platformUrl = 'https://develop.advancedalgos.net/AABrowserAPI/teamSetup/'
// const platformUrl = 'http://localhost:3100/AABrowserAPI/teamSetup/'
const createPlatformTeam = await axios.get(`${platformUrl}${createTeamUrl}`)
.then((result) => {
logger.info('createPlatformTeam:', result)
if(result.data.message === 'Team Name already taken'){
throw new Error(result.data.message)
const createTeamUrl = encodeURI(`${slug}/${name}/${alias}/${botSlug}/${authId}`)
logger.info('createTeamUrl:')
logger.info(JSON.stringify(await createTeamUrl))
const platformUrl = 'https://develop.advancedalgos.net/AABrowserAPI/teamSetup/'
// const platformUrl = 'http://localhost:3100/AABrowserAPI/teamSetup/'
const createPlatformTeam = await axios.get(`${platformUrl}${createTeamUrl}`)
.then((result) => {
logger.info('createPlatformTeam:', result)
if(result.data.message === 'Team Name already taken'){
throw new Error(result.data.message)
}
return result
})
.catch(err =>{
logger.errror('createPlatformTeam err:', err)
throw new Error(err)
})
logger.info('createPlatformTeam: ', await createPlatformTeam)
if(createPlatformTeam === 'Error: Team Name already taken'){
return createPlatformTeam
}
return result
const createTeam = await ctx.db.mutation.createTeam({ data: {name: name, slug: slug, owner: authId, members: {create: {member: {create: {authId: authId, alias: alias, visible:'true', status: { create: { status: 'ACTIVE', reason: `Created team ${name}`}}}}, role: 'OWNER'}}, profile: {create: {avatar: avatar, banner: banner}}, fb: {create: {name: botName, slug: botSlug, kind:'TRADER', avatar: avatar, status: {create: {status: 'ACTIVE', reason: "Cloned on team creation"}}}}, status: {create: {status: 'ACTIVE', reason:"Team created"}}} }, TEAMS_FRAGMENT)
.catch((err) => {
logger.debug(err, 'createTeam error: ')
return err
})
sendTeamCreateConfirmation(email, name, botName)
return createTeam
})
.catch(err =>{
logger.errror('createPlatformTeam err:', err)
throw new Error(err)
})
logger.info('createPlatformTeam: ', await createPlatformTeam)
if(createPlatformTeam === 'Error: Team Name already taken'){
return createPlatformTeam
}
const createTeam = await ctx.db.mutation.createTeam({ data: {name: name, slug: slug, owner: authId, members: {create: {member: {connect: {authId: authId}}, role: 'OWNER'}}, profile: {create: {avatar: avatar, banner: banner}}, fb: {create: {name: botName, slug: botSlug, kind:'TRADER', avatar: avatar, status: {create: {status: 'ACTIVE', reason: "Cloned on team creation"}}}}, status: {create: {status: 'ACTIVE', reason:"Team created"}}} }, TEAMS_FRAGMENT)
.catch((err) => {
logger.debug('createTeam error: ', err)
logger.debug('createTeam error: ')
return err
})
sendTeamCreateConfirmation(email, name, botName)
return createTeam
},
async updateTeamProfile(parent, { slug, owner, description, motto, avatar, banner }, ctx, info) {
return ctx.db.mutation.updateTeam({data:{profile: {update: {description: description, motto: motto, avatar: avatar, banner: banner}}}, where:{slug: slug}}, TEAMS_FRAGMENT)
@@ -231,6 +233,45 @@ const resolvers = {
}
}
const getUser = authId => {
logger.info('getUser')
logger.info(authId)
const API_URL = 'https://app-api.advancedalgos.net/graphql'
return new Promise(resolve => {
try {
const result = axios.post(API_URL, {
query: `query users_UserByAuthId($authId: String!) {
users_UserByAuthId(authId: $authId){
id
alias
email
}
}`,
variables: {
authId: authId
}
}, {
headers: {
'Content-Type': 'application/json'
}
})
.then(result => {
logger.info('getUser result')
logger.info(result.data)
resolve(result.data)
})
.catch(err => {
logger.info('getUser err')
logger.info(err)
throw new Error(err)
})
} catch (error) {
resolve(error)
}
})
}
const db = new Prisma({
fragmentReplacements: extractFragmentReplacements(resolvers),
typeDefs: 'src/generated/prisma.graphql',
+2 -2
View File
@@ -6,9 +6,9 @@ class LoggerService {
new transports.Console({
format: format.combine(
format.colorize(),
format.timestamp({ format: 'YYYY/MM/DD HH:mm' }),
format.timestamp({ format: 'YY/MM/DD HH:mm' }),
format.printf(
info => `${info.timestamp} - ${info.level}: ${info.message}`
info => `${info.timestamp} - ${info.level}: ${JSON.stringify(info.message)}`
)
),
}),
@@ -68,7 +68,7 @@ export class ManageFBEdit extends Component {
const containerName = slug
let avatar = null
if (this.state.avatar === null && fb.avatar === undefined) avatar = 'https://algobotcommstorage.blob.core.windows.net/aateammodule/aa-avatar-default.png'
if (this.state.avatar === null && fb.avatar === undefined) avatar = 'https://aadevelop.blob.core.windows.net/module-teams/module-default/aa-avatar-default.png'
if (fb.avatar !== undefined && fb.avatar !== null) avatar = fb.avatar
if (this.state.avatar !== null) avatar = this.state.avatar
@@ -76,12 +76,12 @@ export class ManageTeamEdit extends Component {
const AzureStorageSAS = process.env.AZURE_STORAGE_SAS_TEAMS
const containerName = team.slug
let avatar = null
if (this.state.avatar === null && team.profile !== null && (team.profile.avatar === undefined || team.profile.avatar === null)) avatar = 'https://algobotcommstorage.blob.core.windows.net/aateammodule/aa-avatar-default.png'
if (this.state.avatar === null && team.profile !== null && (team.profile.avatar === undefined || team.profile.avatar === null)) avatar = 'https://aadevelop.blob.core.windows.net/module-teams/module-default/aa-avatar-default.png'
if (team.profile !== null && team.profile.avatar !== undefined && team.profile.avatar !== null) avatar = team.profile.avatar
if (this.state.avatar !== null) avatar = this.state.avatar
let banner = null
if (this.state.banner === null && team.profile !== null && (team.profile.banner === undefined || team.profile.banner === null)) banner = 'https://algobotcommstorage.blob.core.windows.net/aateammodule/aa-banner-default.png'
if (this.state.banner === null && team.profile !== null && (team.profile.banner === undefined || team.profile.banner === null)) banner = 'https://aadevelop.blob.core.windows.net/module-teams/module-default/aa-banner-default.png'
if (team.profile !== null && team.profile.banner !== undefined && team.profile.banner !== null) banner = team.profile.banner
if (this.state.banner !== null) banner = this.state.banner
console.log('team images: ', avatar, banner)