Merge branch 'master' into feature/member-mangement
This commit is contained in:
commit
4fe572411e
44 files changed
+1307
-919
No files matched your search
@@ -29,7 +29,7 @@ const isLoggedIn = async ctx => {
|
||||
let member = ctxMember(ctx, memberLocationOnContext)
|
||||
let token = ctxToken(ctx, bearerAccessToken)
|
||||
let memberToken
|
||||
console.log('isLoggedIn: ', ctx, member, token)
|
||||
// console.log('isLoggedIn: ', ctx, member, token)
|
||||
if (!member && token) {
|
||||
let scheme, credentials
|
||||
const tokenParts = token.split(' ')
|
||||
@@ -41,16 +41,16 @@ const isLoggedIn = async ctx => {
|
||||
if (/^Bearer$/i.test(scheme)) {
|
||||
token = credentials
|
||||
//verify token
|
||||
console.log('isLoggedIn2 : ', token)
|
||||
// console.log('isLoggedIn2 : ', token)
|
||||
try {
|
||||
memberToken = await validateIdToken(token)
|
||||
const authId = memberToken.sub
|
||||
console.log('isLoggedIn3 : ', await authId, ctx.db.query.member)
|
||||
// console.log('isLoggedIn3 : ', await authId, ctx.db.query.member)
|
||||
exists = await ctx.db.query.member({ where: { authId: authId } })
|
||||
console.log('isLoggedIn4 : ', await exists, createMember )
|
||||
// console.log('isLoggedIn4 : ', await exists, createMember )
|
||||
if (!member && exists === null) {
|
||||
member = await createMember(ctx, memberToken).then(res => {
|
||||
console.log('isLoggedIn5 : ', res)
|
||||
// console.log('isLoggedIn5 : ', res)
|
||||
return res
|
||||
})
|
||||
|
||||
@@ -62,7 +62,7 @@ const isLoggedIn = async ctx => {
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log('isLoggedIn5 : ', await member)
|
||||
// console.log('isLoggedIn5 : ', await member)
|
||||
if (!member) {
|
||||
throw new Error(`Not logged in`)
|
||||
}
|
||||
@@ -95,13 +95,13 @@ 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)
|
||||
// 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)
|
||||
// console.log('directive isOwner 1: ', source, isOwner, type, typeId, memberId)
|
||||
if (isOwner) {
|
||||
return next()
|
||||
}
|
||||
|
||||
@@ -67,6 +67,71 @@ const sendTeamMemberInvite = function(email, team) {
|
||||
return sendVerify
|
||||
}
|
||||
|
||||
const sendTeamCreateConfirmation = function(email, teamName, botName, sessionToken) {
|
||||
const dev = process.env.NODE_ENV === 'development' ? true : false
|
||||
console.log('sendTeamMemberInvite', email, team)
|
||||
const API_KEY = process.env.SG_APIKEY
|
||||
let origin = 'https://teams.advancedalgos.net'
|
||||
if (dev){
|
||||
origin = 'http://localhost:3001'
|
||||
}
|
||||
|
||||
const headers = {
|
||||
'Content-Type': 'application/json',
|
||||
'Access-Control-Allow-Origin' : origin,
|
||||
'Access-Control-Allow-Credentials': 'true'
|
||||
};
|
||||
|
||||
const data = JSON.stringify({
|
||||
"personalizations": [
|
||||
{
|
||||
"to": [
|
||||
{
|
||||
"email": email
|
||||
}
|
||||
],
|
||||
dynamic_template_data: {
|
||||
"aateamdeveloplink": "https://develop.advancedalgos.net/index.html?" + sessionToken,
|
||||
"aateamname": teamName,
|
||||
"aabotname": botName,
|
||||
"subject": "Team " + teamName + " has been created!"
|
||||
},
|
||||
"subject": "Team " + teamName + " has been created!"
|
||||
}
|
||||
],
|
||||
"from": {
|
||||
"email": "noreply@advancedalgos.net",
|
||||
"name": "Advanced Algos Teams"
|
||||
},
|
||||
"reply_to": {
|
||||
"email": "feedback@advancedalgos.net",
|
||||
"name": "Advanced Algos Teams"
|
||||
},
|
||||
"template_id": process.env.SG_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) {
|
||||
return `${error.status}-${error.response.data.errors[0].message}`
|
||||
})
|
||||
return sendTeamCreation
|
||||
}
|
||||
|
||||
const verifyInviteToken = async function(token) {
|
||||
const API_KEY = process.env.SG_APIKEY
|
||||
let verifiedToken
|
||||
@@ -84,4 +149,4 @@ const verifyInviteToken = async function(token) {
|
||||
return verifiedToken
|
||||
}
|
||||
|
||||
module.exports = { sendTeamMemberInvite, verifyInviteToken }
|
||||
module.exports = { sendTeamMemberInvite, sendTeamCreateConfirmation, verifyInviteToken }
|
||||
@@ -1,5 +1,5 @@
|
||||
# source: http://localhost:4466
|
||||
# timestamp: Thu Sep 27 2018 23:28:16 GMT-0700 (Pacific Daylight Time)
|
||||
# timestamp: Fri Oct 05 2018 13:16:40 GMT-0700 (Pacific Daylight Time)
|
||||
|
||||
type AggregateFBStatus {
|
||||
count: Int!
|
||||
@@ -249,6 +249,9 @@ type FinancialBeings implements Node {
|
||||
id: ID!
|
||||
type: FBType
|
||||
kind: FBKind
|
||||
name: String!
|
||||
slug: String!
|
||||
avatar: String
|
||||
team(where: TeamWhereInput): Team
|
||||
status(where: FBStatusWhereInput, orderBy: FBStatusOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [FBStatus!]
|
||||
updatedAt: DateTime!
|
||||
@@ -268,6 +271,9 @@ type FinancialBeingsConnection {
|
||||
input FinancialBeingsCreateInput {
|
||||
type: FBType
|
||||
kind: FBKind
|
||||
name: String!
|
||||
slug: String!
|
||||
avatar: String
|
||||
team: TeamCreateOneWithoutFbInput
|
||||
status: FBStatusCreateManyInput
|
||||
}
|
||||
@@ -280,6 +286,9 @@ input FinancialBeingsCreateManyWithoutTeamInput {
|
||||
input FinancialBeingsCreateWithoutTeamInput {
|
||||
type: FBType
|
||||
kind: FBKind
|
||||
name: String!
|
||||
slug: String!
|
||||
avatar: String
|
||||
status: FBStatusCreateManyInput
|
||||
}
|
||||
|
||||
@@ -299,6 +308,12 @@ enum FinancialBeingsOrderByInput {
|
||||
type_DESC
|
||||
kind_ASC
|
||||
kind_DESC
|
||||
name_ASC
|
||||
name_DESC
|
||||
slug_ASC
|
||||
slug_DESC
|
||||
avatar_ASC
|
||||
avatar_DESC
|
||||
updatedAt_ASC
|
||||
updatedAt_DESC
|
||||
createdAt_ASC
|
||||
@@ -309,6 +324,9 @@ type FinancialBeingsPreviousValues {
|
||||
id: ID!
|
||||
type: FBType
|
||||
kind: FBKind
|
||||
name: String!
|
||||
slug: String!
|
||||
avatar: String
|
||||
updatedAt: DateTime!
|
||||
createdAt: DateTime!
|
||||
}
|
||||
@@ -355,6 +373,9 @@ input FinancialBeingsSubscriptionWhereInput {
|
||||
input FinancialBeingsUpdateInput {
|
||||
type: FBType
|
||||
kind: FBKind
|
||||
name: String
|
||||
slug: String
|
||||
avatar: String
|
||||
team: TeamUpdateOneWithoutFbInput
|
||||
status: FBStatusUpdateManyInput
|
||||
}
|
||||
@@ -371,6 +392,9 @@ input FinancialBeingsUpdateManyWithoutTeamInput {
|
||||
input FinancialBeingsUpdateWithoutTeamDataInput {
|
||||
type: FBType
|
||||
kind: FBKind
|
||||
name: String
|
||||
slug: String
|
||||
avatar: String
|
||||
status: FBStatusUpdateManyInput
|
||||
}
|
||||
|
||||
@@ -454,6 +478,126 @@ input FinancialBeingsWhereInput {
|
||||
|
||||
"""All values that are not contained in given list."""
|
||||
kind_not_in: [FBKind!]
|
||||
name: String
|
||||
|
||||
"""All values that are not equal to given value."""
|
||||
name_not: String
|
||||
|
||||
"""All values that are contained in given list."""
|
||||
name_in: [String!]
|
||||
|
||||
"""All values that are not contained in given list."""
|
||||
name_not_in: [String!]
|
||||
|
||||
"""All values less than the given value."""
|
||||
name_lt: String
|
||||
|
||||
"""All values less than or equal the given value."""
|
||||
name_lte: String
|
||||
|
||||
"""All values greater than the given value."""
|
||||
name_gt: String
|
||||
|
||||
"""All values greater than or equal the given value."""
|
||||
name_gte: String
|
||||
|
||||
"""All values containing the given string."""
|
||||
name_contains: String
|
||||
|
||||
"""All values not containing the given string."""
|
||||
name_not_contains: String
|
||||
|
||||
"""All values starting with the given string."""
|
||||
name_starts_with: String
|
||||
|
||||
"""All values not starting with the given string."""
|
||||
name_not_starts_with: String
|
||||
|
||||
"""All values ending with the given string."""
|
||||
name_ends_with: String
|
||||
|
||||
"""All values not ending with the given string."""
|
||||
name_not_ends_with: String
|
||||
slug: String
|
||||
|
||||
"""All values that are not equal to given value."""
|
||||
slug_not: String
|
||||
|
||||
"""All values that are contained in given list."""
|
||||
slug_in: [String!]
|
||||
|
||||
"""All values that are not contained in given list."""
|
||||
slug_not_in: [String!]
|
||||
|
||||
"""All values less than the given value."""
|
||||
slug_lt: String
|
||||
|
||||
"""All values less than or equal the given value."""
|
||||
slug_lte: String
|
||||
|
||||
"""All values greater than the given value."""
|
||||
slug_gt: String
|
||||
|
||||
"""All values greater than or equal the given value."""
|
||||
slug_gte: String
|
||||
|
||||
"""All values containing the given string."""
|
||||
slug_contains: String
|
||||
|
||||
"""All values not containing the given string."""
|
||||
slug_not_contains: String
|
||||
|
||||
"""All values starting with the given string."""
|
||||
slug_starts_with: String
|
||||
|
||||
"""All values not starting with the given string."""
|
||||
slug_not_starts_with: String
|
||||
|
||||
"""All values ending with the given string."""
|
||||
slug_ends_with: String
|
||||
|
||||
"""All values not ending with the given string."""
|
||||
slug_not_ends_with: String
|
||||
avatar: String
|
||||
|
||||
"""All values that are not equal to given value."""
|
||||
avatar_not: String
|
||||
|
||||
"""All values that are contained in given list."""
|
||||
avatar_in: [String!]
|
||||
|
||||
"""All values that are not contained in given list."""
|
||||
avatar_not_in: [String!]
|
||||
|
||||
"""All values less than the given value."""
|
||||
avatar_lt: String
|
||||
|
||||
"""All values less than or equal the given value."""
|
||||
avatar_lte: String
|
||||
|
||||
"""All values greater than the given value."""
|
||||
avatar_gt: String
|
||||
|
||||
"""All values greater than or equal the given value."""
|
||||
avatar_gte: String
|
||||
|
||||
"""All values containing the given string."""
|
||||
avatar_contains: String
|
||||
|
||||
"""All values not containing the given string."""
|
||||
avatar_not_contains: String
|
||||
|
||||
"""All values starting with the given string."""
|
||||
avatar_starts_with: String
|
||||
|
||||
"""All values not starting with the given string."""
|
||||
avatar_not_starts_with: String
|
||||
|
||||
"""All values ending with the given string."""
|
||||
avatar_ends_with: String
|
||||
|
||||
"""All values not ending with the given string."""
|
||||
avatar_not_ends_with: String
|
||||
updatedAt: DateTime
|
||||
|
||||
"""All values that are not equal to given value."""
|
||||
|
||||
@@ -15,6 +15,7 @@ const TEAMS_CONNECTIONS_FRAGMENT = gql`{
|
||||
createdAt
|
||||
profile {
|
||||
avatar
|
||||
banner
|
||||
description
|
||||
motto
|
||||
updatedAt
|
||||
@@ -33,6 +34,18 @@ const TEAMS_CONNECTIONS_FRAGMENT = gql`{
|
||||
createdAt
|
||||
}
|
||||
}
|
||||
fb {
|
||||
id
|
||||
name
|
||||
slug
|
||||
avatar
|
||||
kind
|
||||
status {
|
||||
status
|
||||
reason
|
||||
createdAt
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
@@ -31,6 +31,18 @@ const TEAMS_FRAGMENT = gql`{
|
||||
createdAt
|
||||
}
|
||||
}
|
||||
fb {
|
||||
id
|
||||
name
|
||||
slug
|
||||
avatar
|
||||
kind
|
||||
status {
|
||||
status
|
||||
reason
|
||||
createdAt
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
module.exports = TEAMS_FRAGMENT
|
||||
+69
-86
@@ -8,34 +8,20 @@ const {
|
||||
const { makeExecutableSchema } = require('graphql-tools')
|
||||
const { importSchema } = require('graphql-import')
|
||||
const parser = require('fast-xml-parser')
|
||||
var axios = require('axios')
|
||||
|
||||
const checkJwt = require('./auth/middleware/jwt')
|
||||
const { getMember } = require('./auth/middleware/getMember')
|
||||
const { validateIdToken } = require('./auth/validateIdToken')
|
||||
const { directiveResolvers } = require('./auth/authDirectives')
|
||||
|
||||
const { sendTeamMemberInvite, verifyInviteToken } = require('./email/sendgrid')
|
||||
|
||||
const {
|
||||
createStoragePipline,
|
||||
createServiceURL,
|
||||
listContainers,
|
||||
createContainer,
|
||||
createBlob,
|
||||
uploadBlob,
|
||||
downloadBlob,
|
||||
deleteBlob,
|
||||
deleteContainer
|
||||
} = require('./storage/azure')
|
||||
//var azure = require('azure-storage')
|
||||
const Azure = require("@azure/storage-blob")
|
||||
const { createSASQueryURL } = require('./storage/azure')
|
||||
const azureAccount = process.env.AZURE_STORAGE_ACCOUNT
|
||||
const azureKey = process.env.AZURE_STORAGE_ACCESS_KEY
|
||||
const azureStorageUrl = process.env.AZURE_STORAGE_URL
|
||||
|
||||
var debug = require('debug')('http')
|
||||
, http = require('http')
|
||||
, name = 'My App';
|
||||
const { sendTeamMemberInvite, sendTeamCreateConfirmation, verifyInviteToken } = require('./email/sendgrid')
|
||||
|
||||
const TEAMS_FRAGMENT = require('./graphql/TeamsFragment')
|
||||
const TEAMS_CONNECTIONS_FRAGMENT = require('./graphql/TeamsConnectionsFragment')
|
||||
@@ -93,9 +79,8 @@ const resolvers = {
|
||||
async teamWithRole(parent, { teamId, role }, ctx, info) {
|
||||
return ctx.db.query.teamsConnection({where: {AND: [{id: teamId},{members_some:{role: role}}]}, first:1}, info)
|
||||
},
|
||||
async teamsByOwner(parent, args, ctx, info) {
|
||||
const authId = ctx.request.user.sub
|
||||
return ctx.db.query.teams({where: { owner: authId }, orderBy:'updatedAt_DESC'}, TEAMS_FRAGMENT)
|
||||
async teamsByOwner(parent, { ownerId }, ctx, info) {
|
||||
return ctx.db.query.teams({where: { owner: ownerId }, orderBy:'updatedAt_DESC'}, TEAMS_FRAGMENT)
|
||||
},
|
||||
async teamsByRole(parent, args, ctx, info) {
|
||||
const authId = ctx.request.user.sub
|
||||
@@ -136,6 +121,16 @@ const resolvers = {
|
||||
}
|
||||
return member
|
||||
},
|
||||
async sendMemberInviteSG(parent, { email, teamId }, ctx, info) {
|
||||
const team = await ctx.db.query.team({ where: { id: teamId } }, TEAMS_FRAGMENT)
|
||||
const addMember = await ctx.db.mutation.upsertTeamMembers({
|
||||
where:{email: email},
|
||||
create:{role:'MEMBER', email:email, team: {connect: {id: teamId}}, status:{create:{status: 'INVITED', reason: `Invited by ${team.members[0].member.alias}`}}},
|
||||
update:{role: 'MEMBER', email: email, team: {connect: {id: teamId}}, status:{create:{status: 'INVITED', reason: `Invite resent by ${team.members[0].member.alias}`}}}},
|
||||
`{ id }`)
|
||||
const sendInvite = await sendTeamMemberInvite(email, team)
|
||||
return sendInvite
|
||||
},
|
||||
async verifyTeamInvite(parent, { token }, ctx, info) {
|
||||
let verifiedToken = null
|
||||
let team = null
|
||||
@@ -154,16 +149,52 @@ const resolvers = {
|
||||
}
|
||||
return team
|
||||
},
|
||||
async createTeam(parent, { name, slug }, ctx, info) {
|
||||
async createTeam(parent, { name, slug, botName, botSlug }, ctx, info) {
|
||||
console.log('createTeam ctx:', ctx.request.user)
|
||||
const authId = ctx.request.user.sub
|
||||
return ctx.db.mutation.createTeam({ data: { name: name, slug: slug, owner: authId, members: { create: { member:{ connect:{ authId: authId} }, role: 'OWNER' } }, profile:{create:{avatar:"a"} } } }, TEAMS_FRAGMENT)
|
||||
const encodedAuthId = encodeURI(authId)
|
||||
const getUserModuleUser = await axios.get(`https://users-api.advancedalgos.net/graphql?query=%7B%0A%20%20userByAuthId(authId%3A%22${encodedAuthId}%22)%7B%0A%20%20%20%20id%0A%09%09email%0A%20%20%20%20alias%0A%20%20%7D%0A%7D`)
|
||||
|
||||
console.log('getUserModuleUserId: ', await getUserModuleUser.data)
|
||||
|
||||
const alias = await getUserModuleUser.data.data.userByAuthId.alias
|
||||
const email = await 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'
|
||||
console.log('getUserModuleUserId: ', alias, email)
|
||||
/*
|
||||
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) => {
|
||||
console.log('createTeam error: ', err)
|
||||
return err
|
||||
})
|
||||
*/
|
||||
const createTeamUrl = encodeURI(`${slug}/${name}/${alias}/${botSlug}`)
|
||||
// const platformUrl = 'https://develop.advancedalgos.net/AABrowserAPI/teamSetup/'
|
||||
const platformUrl = 'http://localhost:1337/AABrowserAPI/teamSetup/'
|
||||
const createPlatformTeam = await axios.get(`${platformUrl}${createTeamUrl}`)
|
||||
console.log('createPlatformTeam: ', await createPlatformTeam)
|
||||
|
||||
|
||||
/* update session token on user module
|
||||
const updateUserSession = await axios.post('https://users-api.advancedalgos.net/graphql', {
|
||||
query: 'mutation { language }'
|
||||
})
|
||||
*/
|
||||
|
||||
sendTeamCreateConfirmation(email, name, botName, sessionToken)
|
||||
|
||||
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)
|
||||
.catch((err) => {
|
||||
console.log('createTeam error: ', err)
|
||||
return err
|
||||
})
|
||||
},
|
||||
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)
|
||||
async updateFB(parent, { teamId, avatar}, ctx, info) {
|
||||
return ctx.db.mutation.updateTeam({data:{profile: {update: {avatar: avatar}}}, where:{slug: teamId}}, info)
|
||||
.catch((err) => {
|
||||
console.log('createTeam error: ', err)
|
||||
return err
|
||||
@@ -179,66 +210,9 @@ const resolvers = {
|
||||
})
|
||||
},
|
||||
async getAzureSAS(parent, { teamSlug }, ctx, info) {
|
||||
// Create start and expiry times
|
||||
let today = new Date()
|
||||
let week = new Date()
|
||||
week.setDate(today.getDate() + 7)
|
||||
// Create SharedKeyCredential and attach to pipline
|
||||
const SKC = new Azure.SharedKeyCredential(azureAccount, azureKey)
|
||||
const pipeline = Azure.StorageURL.newPipeline(SKC)
|
||||
// Create container URL
|
||||
const serviceURL = new Azure.ServiceURL(azureStorageUrl, pipeline)
|
||||
const containerName = teamSlug
|
||||
const containerURL = Azure.ContainerURL.fromServiceURL(serviceURL, containerName)
|
||||
|
||||
let marker
|
||||
let containerCheck = null
|
||||
do {
|
||||
const listContainersResponse = await serviceURL.listContainersSegment(
|
||||
Azure.Aborter.None,
|
||||
marker,
|
||||
)
|
||||
console.log(`ContainerCheck marker: `, listContainersResponse)
|
||||
marker = listContainersResponse.marker;
|
||||
for (const container of listContainersResponse.containerItems) {
|
||||
console.log(`ContainerCheck: ${container.name} | ${containerName} | ${marker}`)
|
||||
if(container.name === containerName){
|
||||
containerCheck = container.name
|
||||
}
|
||||
}
|
||||
} while (marker)
|
||||
let newContainer
|
||||
if(containerCheck === null){
|
||||
newContainer = await containerURL.create(Azure.Aborter.None, { access: 'blob' })
|
||||
}
|
||||
console.log('getAzureSAS container: ', containerURL, containerCheck, newContainer)
|
||||
|
||||
// Set permissions for service, resource types and containers
|
||||
const SASServicePerms = Azure.AccountSASServices.parse('b')
|
||||
const SASResourceTypes = Azure.AccountSASResourceTypes.parse('co')
|
||||
const SASContainerPerms = Azure.ContainerSASPermissions.parse('rwl')
|
||||
// Generate SAS url
|
||||
const SASQueryParameters = Azure.generateAccountSASQueryParameters(
|
||||
{
|
||||
version: '2017-11-09',
|
||||
permissions: SASContainerPerms,
|
||||
startTime: today,
|
||||
expiryTime: week,
|
||||
protocol: 'https',
|
||||
services: SASServicePerms,
|
||||
resourceTypes: SASResourceTypes
|
||||
}, SKC )
|
||||
return SASQueryParameters
|
||||
},
|
||||
async sendMemberInviteSG(parent, { email, teamId }, ctx, info) {
|
||||
const team = await ctx.db.query.team({ where: { id: teamId } }, TEAMS_FRAGMENT)
|
||||
const addMember = await ctx.db.mutation.upsertTeamMembers({
|
||||
where:{email: email},
|
||||
create:{role:'MEMBER', email:email, team: {connect: {id: teamId}}, status:{create:{status: 'INVITED', reason: `Invited by ${team.members[0].member.alias}`}}},
|
||||
update:{role: 'MEMBER', email: email, team: {connect: {id: teamId}}, status:{create:{status: 'INVITED', reason: `Invite resent by ${team.members[0].member.alias}`}}}},
|
||||
`{ id }`)
|
||||
const sendInvite = await sendTeamMemberInvite(email, team)
|
||||
return sendInvite
|
||||
const SASUrl = createSASQueryURL(teamSlug)
|
||||
console.log('createSASQueryURL: ', SASUrl)
|
||||
return SASUrl
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -283,13 +257,22 @@ server.express.use(
|
||||
|
||||
server.express.post(server.options.endpoint, (req, res, done) => getUser(req, res, done, db))
|
||||
|
||||
const whitelist = [
|
||||
let whitelist = [
|
||||
'http://localhost:3000',
|
||||
'http://localhost:3001',
|
||||
'http://localhost:3002',
|
||||
'http://localhost:4000',
|
||||
'http://localhost:4002'
|
||||
'http://localhost:4002',
|
||||
'http://localhost:1337',
|
||||
'https://teams.advancedalgos.net',
|
||||
'https://users.advancedalgos.net',
|
||||
'https://users-api.advancedalgos.net',
|
||||
'https://keyvault.advancedalgos.net',
|
||||
'https://keyvault-api.advancedalgos.net',
|
||||
'https://aawebdevelop.azurewebsites.net',
|
||||
'https://develop.advancedalgos.net'
|
||||
]
|
||||
|
||||
const corsOptionsDelegate = (req, callback) => {
|
||||
var corsOptions
|
||||
if (whitelist.indexOf(req.header('Origin')) !== -1) {
|
||||
|
||||
@@ -11,7 +11,7 @@ type Query {
|
||||
teamByName(name: String!): Team
|
||||
teamById(teamId: String!): Team
|
||||
teamWithRole(teamId: String!, role: String!): Team
|
||||
teamsByOwner: [Team!]! @isAuthenticated
|
||||
teamsByOwner(ownerId: String!): [Team!]! @isAuthenticated
|
||||
teamsByRole: [Team!]! @isAuthenticated
|
||||
owner: Member @isAuthenticated
|
||||
currentMember: Member @isAuthenticated
|
||||
@@ -21,8 +21,9 @@ type Query {
|
||||
type Mutation {
|
||||
authenticate(idToken: String!): Member
|
||||
verifyTeamInvite(token: String!): TeamMembers
|
||||
createTeam(name: String!, slug: String!): Team @isAuthenticated
|
||||
createTeam(name: String!, slug: String!, botName: String!, botSlug: String!): Team @isAuthenticated
|
||||
updateTeamProfile(slug: String!, description: String, motto: String, avatar: String, banner: String): Team @isAuthenticated
|
||||
updateFB(teamId: String!, avatar: String): FinancialBeings @isAuthenticated
|
||||
deleteTeam(slug: String!): Team @isAuthenticated @isOwner(type: "Team")
|
||||
getAzureSAS(teamSlug: String!):String
|
||||
sendMemberInviteSG(email: String!, teamId: String!): String
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
const Azure = require('@azure/storage-blob')
|
||||
const Azure = require("@azure/storage-blob")
|
||||
const azureAccount = process.env.AZURE_STORAGE_ACCOUNT
|
||||
const azureKey = process.env.AZURE_STORAGE_ACCESS_KEY
|
||||
const azureStorageUrl = process.env.AZURE_STORAGE_URL
|
||||
|
||||
/* Create Azure Storage pipeline
|
||||
* @accountName: Azure Blob Storage account name (required) - Environment variable
|
||||
* @accountKey: Azure Blob Storage storage key (required) - Environment variable
|
||||
*/
|
||||
const createStoragePipline = async (accountNAme, accountKey) => {
|
||||
const createStoragePipline = async (accountName, accountKey) => {
|
||||
return Azure.StorageURL.newPipeline(
|
||||
new Azure.SharedKeyCredential(accountName, accountKey)
|
||||
)
|
||||
@@ -120,6 +123,60 @@ const deleteContainer = async (containerURL) => {
|
||||
return true
|
||||
}
|
||||
|
||||
const createSASQueryURL = async (containerName) => {
|
||||
let today = new Date()
|
||||
let week = new Date()
|
||||
week.setDate(today.getDate() + 7)
|
||||
// Create SharedKeyCredential and attach to pipline
|
||||
const SKC = new Azure.SharedKeyCredential(azureAccount, azureKey)
|
||||
const pipeline = Azure.StorageURL.newPipeline(SKC)
|
||||
// Create container URL
|
||||
const serviceURL = new Azure.ServiceURL(azureStorageUrl, pipeline)
|
||||
const containerURL = Azure.ContainerURL.fromServiceURL(serviceURL, containerName)
|
||||
|
||||
//list container and check if already exists.
|
||||
let marker
|
||||
let containerCheck = null
|
||||
do {
|
||||
const listContainersResponse = await serviceURL.listContainersSegment(
|
||||
Azure.Aborter.None,
|
||||
marker,
|
||||
)
|
||||
// console.log(`ContainerCheck marker: `, listContainersResponse)
|
||||
marker = listContainersResponse.marker;
|
||||
for (const container of listContainersResponse.containerItems) {
|
||||
// console.log(`ContainerCheck: ${container.name} | ${containerName} | ${marker}`)
|
||||
if(container.name === containerName){
|
||||
containerCheck = container.name
|
||||
}
|
||||
}
|
||||
} while (marker)
|
||||
|
||||
// if container doesn't exist, create one
|
||||
let newContainer
|
||||
if(containerCheck === null){
|
||||
newContainer = await containerURL.create(Azure.Aborter.None, { access: 'blob' })
|
||||
}
|
||||
console.log('createSASQueryURL container: ', containerURL, containerCheck, newContainer)
|
||||
|
||||
// Set permissions for service, resource types and containers
|
||||
const SASContainerPerms = await Azure.AccountSASPermissions.parse('rwlacu')
|
||||
const SASServicePerms = await Azure.AccountSASServices.parse('b')
|
||||
const SASResourceTypes = await Azure.AccountSASResourceTypes.parse('co')
|
||||
console.log('createSASQueryURL permissions: ', SASServicePerms, SASResourceTypes, SASContainerPerms)
|
||||
// Generate SAS url
|
||||
const SASQueryParameters = await Azure.generateBlobSASQueryParameters(
|
||||
{
|
||||
version: '2017-11-09',
|
||||
protocol: 'https,http',
|
||||
expiryTime: week,
|
||||
permissions: 'rwlac',
|
||||
containerName: containerName
|
||||
}, SKC )
|
||||
console.log('createSASQueryURL SASQueryParameters: ', containerURL.url, SASQueryParameters)
|
||||
return SASQueryParameters
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createStoragePipline,
|
||||
createServiceURL,
|
||||
@@ -129,5 +186,6 @@ module.exports = {
|
||||
uploadBlob,
|
||||
downloadBlob,
|
||||
deleteBlob,
|
||||
deleteContainer
|
||||
deleteContainer,
|
||||
createSASQueryURL
|
||||
}
|
||||
Reference in new issue
Block a user