diff --git a/api/src/index.js b/api/src/index.js index 5ec890d4b..e6fc19e54 100644 --- a/api/src/index.js +++ b/api/src/index.js @@ -15,14 +15,11 @@ const { validateIdToken } = require('./auth/validateIdToken') const { directiveResolvers } = require('./auth/authDirectives') 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 TEAMS_FRAGMENT = require('./graphql/TeamsFragment') const TEAMS_CONNECTIONS_FRAGMENT = require('./graphql/TeamsConnectionsFragment') @@ -77,7 +74,7 @@ const resolvers = { return ctx.db.query.team({ where: { name: name } }, `{ name }`) }, async teamsByOwner(parent, { ownerId }, ctx, info) { - console.log('teamsByOwner: ', ctx.user) + console.log('teamsByOwner: ', ctx) return ctx.db.query.teams({where: { owner: ownerId }, orderBy:'updatedAt_DESC'}, TEAMS_FRAGMENT) }, async owner(parent, args, ctx, info) { @@ -137,60 +134,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) - - //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('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 + const SASUrl = createSASQueryURL(teamSlug) + console.log('createSASQueryURL: ', SASUrl) + return SASUrl } } } @@ -235,13 +181,26 @@ 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' ] +if(process.env.NODE_ENV === 'production'){ + whitelist = [ + 'https://teams.advancedalgos.net', + 'https://users.advancedalgos.net', + 'https://users-api.advancedalgos.net', + 'https://keyvault.advancedalgos.net', + 'https://keyvault-api.advancedalgos.net', + 'http://localhost:1337' + ] +} + + const corsOptionsDelegate = (req, callback) => { var corsOptions if (whitelist.indexOf(req.header('Origin')) !== -1) { diff --git a/api/src/storage/azure.js b/api/src/storage/azure.js index abeea558e..b718d6ef5 100644 --- a/api/src/storage/azure.js +++ b/api/src/storage/azure.js @@ -1,4 +1,7 @@ -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 @@ -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 } diff --git a/client/package-lock.json b/client/package-lock.json index 4a43e9c8d..b1ce31784 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -5,9 +5,9 @@ "requires": true, "dependencies": { "@advancedalgos/web-components": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/@advancedalgos/web-components/-/web-components-0.0.1.tgz", - "integrity": "sha512-RDi7oR5oY4HbcXdzTDhtgYVHRO+/ApBMossZ/UkCrI2lYAWhQaq4mYaKaJ2mtVKnwV1BkeOLFE6rbPZwIkhXJA==", + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/@advancedalgos/web-components/-/web-components-0.0.5.tgz", + "integrity": "sha512-mgaS2AwtVcbP0W8/Rk95TNFTrDmp21rDmoqrO177WGLCcTH5n3rHisQtrdVaEvLiUGoZ/8us/GeclljVJP1edw==", "requires": { "@azure/storage-blob": "^10.1.0-preview", "@material-ui/core": "^3.0.3", @@ -35,9 +35,9 @@ } }, "@types/node": { - "version": "9.6.32", - "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.32.tgz", - "integrity": "sha512-5+L3wQ+FHoQ589EaH6rYICleuj8gnunq+1CJkM9fxklirErIOv+kxm3s/vecYnpJOYnFowE5uUizcb3hgjHUug==" + "version": "9.6.34", + "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.34.tgz", + "integrity": "sha512-PzJpSs2afoYqBA4yLBgaKUdZRk8+1yvkxcUBW6958h4vYOC+pc4k4C+QmQ6AO5Pt7uA4EIIboFog6YNCuITD0g==" }, "apollo-cache": { "version": "1.1.17", diff --git a/client/package.json b/client/package.json index 8b5491695..c40d1672e 100644 --- a/client/package.json +++ b/client/package.json @@ -68,7 +68,7 @@ "workbox-cli": "^3.4.1" }, "dependencies": { - "@advancedalgos/web-components": "0.0.1", + "@advancedalgos/web-components": "0.0.5", "@azure/storage-blob": "^10.0.0-preview", "@material-ui/core": "^3.0.3", "@material-ui/icons": "^3.0.1", diff --git a/client/src/views/dashboard/FinancialBeings.js b/client/src/views/dashboard/FinancialBeings.js index be6ac2aba..c4d13ee80 100644 --- a/client/src/views/dashboard/FinancialBeings.js +++ b/client/src/views/dashboard/FinancialBeings.js @@ -4,7 +4,7 @@ import PropTypes from 'prop-types' import Typography from '@material-ui/core/Typography' import { withStyles } from '@material-ui/core/styles' -import { MessageCard } from '../common/' +import { MessageCard } from '@advancedalgos/web-components' const styles = theme => ({ tableContainer: { diff --git a/client/src/views/dashboard/TeamMembers.js b/client/src/views/dashboard/TeamMembers.js index 8d86d4155..1bbb78295 100644 --- a/client/src/views/dashboard/TeamMembers.js +++ b/client/src/views/dashboard/TeamMembers.js @@ -4,7 +4,7 @@ import PropTypes from 'prop-types' import Typography from '@material-ui/core/Typography' import { withStyles } from '@material-ui/core/styles' -import { MessageCard } from '../common/' +import { MessageCard } from '@advancedalgos/web-components' const styles = theme => ({ tableContainer: { diff --git a/client/src/views/dashboard/components/DashTeam.js b/client/src/views/dashboard/components/DashTeam.js index 1f6fc42c7..cc2f3b1b4 100644 --- a/client/src/views/dashboard/components/DashTeam.js +++ b/client/src/views/dashboard/components/DashTeam.js @@ -11,7 +11,7 @@ import GET_TEAMS_BY_OWNER from '../../../graphql/teams/GetTeamsByOwnerQuery' import DashTeamItem from './DashTeamItem' import CreateTeamDialog from './CreateTeamDialog' -import { MessageCard } from '../../common/' +import { MessageCard } from '@advancedalgos/web-components' import { isDefined, isString } from '../../../utils/js-helpers' import { getItem } from '../../../utils/local-storage' diff --git a/client/src/views/dashboard/components/DashTeamItem.js b/client/src/views/dashboard/components/DashTeamItem.js index e917b9006..db7f1b481 100644 --- a/client/src/views/dashboard/components/DashTeamItem.js +++ b/client/src/views/dashboard/components/DashTeamItem.js @@ -35,13 +35,15 @@ const styles = theme => ({ } }) +const placeholder = 'data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22288%22%20height%3D%22225%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20288%20225%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_164edaf95ee%20text%20%7B%20fill%3A%23eceeef%3Bfont-weight%3Abold%3Bfont-family%3AArial%2C%20Helvetica%2C%20Open%20Sans%2C%20sans-serif%2C%20monospace%3Bfont-size%3A14pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_164edaf95ee%22%3E%3Crect%20width%3D%22288%22%20height%3D%22225%22%20fill%3D%22%2355595c%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%2296.32500076293945%22%20y%3D%22118.8%22%3EThumbnail%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E' // eslint-disable-line max-len + export const DashTeamItem = ({ classes, team }) => (
diff --git a/client/src/views/dashboard/components/ManageTeamEdit.js b/client/src/views/dashboard/components/ManageTeamEdit.js index a069787c4..900dfa62f 100644 --- a/client/src/views/dashboard/components/ManageTeamEdit.js +++ b/client/src/views/dashboard/components/ManageTeamEdit.js @@ -15,8 +15,6 @@ import Typography from '@material-ui/core/Typography' import { MessageCard, ImageUpload } from '@advancedalgos/web-components' -import { getItem } from '../../../utils/local-storage' - import UPDATE_TEAM_PROFILE from '../../../graphql/teams/UpdateTeamProfileMutation' import GET_TEAMS_BY_OWNER from '../../../graphql/teams/GetTeamsByOwnerQuery' @@ -51,6 +49,7 @@ export class ManageTeamEdit extends Component { const description = props.team.profile.description || '' const avatar = props.team.profile.avatar || '' const banner = props.team.profile.banner || '' + this.authId = props.authId this.state = { open: false, @@ -62,14 +61,15 @@ export class ManageTeamEdit extends Component { } render () { - console.log(this.props, this.props.slug) + console.log('ManageTeamEdit ', this.props, this.props.slug, this.props.team) const { classes, team } = this.props return ( @@ -114,7 +114,7 @@ export class ManageTeamEdit extends Component { {(getAzureSAS, { loading, error, data }) => { - console.log('getAzureSAS: ', loading, error, data) + console.log('getAzureSAS: ', loading, error, data, team.profile) const AzureStorageUrl = process.env.AZURE_STORAGE_URL const containerName = team.slug let AzureSASURL @@ -124,16 +124,46 @@ export class ManageTeamEdit extends Component { getAzureSAS({ variables: { teamSlug: containerName } }) } + let avatar = null + if (this.state.avatar !== null) avatar = this.state.avatar + if (team.profile !== null && team.profile.avatar !== undefined && team.profile.avatar !== null) avatar = team.profile.avatar + + let banner = null + if (this.state.banner !== null) banner = this.state.banner + if (team.profile !== null && team.profile.banner !== undefined && team.profile.banner !== null) banner = team.profile.banner + console.log('team images: ', avatar, banner) + if (loading || data === undefined) { return () } else { return ( + ) @@ -230,24 +262,22 @@ export class ManageTeamEdit extends Component { handleAvatar (avatarUrl) { console.log('handleAvatar: ', avatarUrl) - this.setState({ avatar: avatarUrl }) + this.setState({ avatar: `${avatarUrl}?${Math.random()}` }) } handleBanner (bannerUrl) { console.log('handleBanner: ', bannerUrl) - this.setState({ banner: bannerUrl }) + this.setState({ banner: `${bannerUrl}?${Math.random()}` }) } async handleSubmit (e, updateTeamProfile, slug) { console.log('handleSubmit: ', this.state) e.preventDefault() - const currentUser = await getItem('user') - let authId = JSON.parse(currentUser) - authId = authId.authId + await updateTeamProfile({ variables: { slug, - owner: authId, + owner: this.authId, description: this.state.description, motto: this.state.motto, avatar: this.state.avatar, @@ -261,7 +291,8 @@ export class ManageTeamEdit extends Component { ManageTeamEdit.propTypes = { classes: PropTypes.object.isRequired, slug: PropTypes.string.isRequired, - team: PropTypes.object + team: PropTypes.object, + authId: PropTypes.string.isRequired } export default withStyles(styles)(ManageTeamEdit) diff --git a/client/src/views/dashboard/components/ManageTeamsList.js b/client/src/views/dashboard/components/ManageTeamsList.js index d72921486..816a4db88 100644 --- a/client/src/views/dashboard/components/ManageTeamsList.js +++ b/client/src/views/dashboard/components/ManageTeamsList.js @@ -4,6 +4,7 @@ import { Query } from 'react-apollo' import { withStateHandlers, lifecycle, compose } from 'recompose' import Grid from '@material-ui/core/Grid' +import { MessageCard } from '@advancedalgos/web-components' import { withStyles } from '@material-ui/core/styles' import { isDefined, isString } from '../../../utils/js-helpers' @@ -13,7 +14,6 @@ import GET_TEAMS_BY_OWNER from '../../../graphql/teams/GetTeamsByOwnerQuery' import ManageTeamsItem from './ManageTeamsItem' import CreateTeamDialog from './CreateTeamDialog' -import { MessageCard } from '../../common/' const styles = theme => ({ heroContent: { diff --git a/client/src/views/dashboard/settings.js b/client/src/views/dashboard/settings.js index d28df4d79..f427a01e2 100644 --- a/client/src/views/dashboard/settings.js +++ b/client/src/views/dashboard/settings.js @@ -4,7 +4,7 @@ import PropTypes from 'prop-types' import Typography from '@material-ui/core/Typography' import { withStyles } from '@material-ui/core/styles' -import { MessageCard } from '../common/' +import { MessageCard } from '@advancedalgos/web-components' const styles = theme => ({ tableContainer: {