diff --git a/TopSpace/DevTeam.js b/TopSpace/DevTeam.js index a43ceb911..c75577ca0 100644 --- a/TopSpace/DevTeam.js +++ b/TopSpace/DevTeam.js @@ -4,7 +4,7 @@ function newDevTeam() { let thisObject = { container: undefined, draw: draw, - getContainer: getContainer, + getContainer: getContainer, initialize: initialize }; @@ -32,11 +32,15 @@ function newDevTeam() { sharedStatus = pSharedStatus; - if (window.USER_PROFILE.devTeams.length === 0) { + let storedTeams = window.localStorage.getItem('userTeams'); + + if (storedTeams === null || storedTeams.length === 0) { + window.TEAMS = ""; label = NOT_FOUND; } else { - window.DEV_TEAM = window.USER_PROFILE.devTeams[sharedStatus.currentDevTeamIndex].codeName; - label = window.USER_PROFILE.devTeams[sharedStatus.currentDevTeamIndex].displayName; + storedTeams = JSON.parse(storedTeams) + window.TEAMS = storedTeams; + label = storedTeams[sharedStatus.currentDevTeamIndex].name; } thisObject.container.eventHandler.listenToEvent("onMouseClick", onClick); @@ -44,20 +48,20 @@ function newDevTeam() { function onClick() { - if (sharedStatus.currentDevTeamIndex + 1 === window.USER_PROFILE.devTeams.length) { + if (sharedStatus.currentDevTeamIndex + 1 === window.TEAMS.length) { sharedStatus.currentDevTeamIndex = 0; - window.DEV_TEAM = window.USER_PROFILE.devTeams[sharedStatus.currentDevTeamIndex].codeName; - label = window.USER_PROFILE.devTeams[sharedStatus.currentDevTeamIndex].displayName; + window.DEV_TEAM = window.TEAMS[sharedStatus.currentDevTeamIndex].slug; + label = window.TEAMS[sharedStatus.currentDevTeamIndex].name; sharedStatus.eventHandler.raiseEvent("devTeam Changed"); return; } - if (sharedStatus.currentDevTeamIndex + 1 < window.USER_PROFILE.devTeams.length) { + if (sharedStatus.currentDevTeamIndex + 1 < window.TEAMS.length) { sharedStatus.currentDevTeamIndex++; - window.DEV_TEAM = window.USER_PROFILE.devTeams[sharedStatus.currentDevTeamIndex].codeName; - label = window.USER_PROFILE.devTeams[sharedStatus.currentDevTeamIndex].displayName; + window.DEV_TEAM = window.TEAMS[sharedStatus.currentDevTeamIndex].slug; + label = window.TEAMS[sharedStatus.currentDevTeamIndex].name; sharedStatus.eventHandler.raiseEvent("devTeam Changed"); return; } @@ -100,4 +104,4 @@ function newDevTeam() { browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)'; browserCanvasContext.fillText(label, point.x, point.y); } -} \ No newline at end of file +} diff --git a/TopSpace/Login.js b/TopSpace/Login.js index 24d84b25c..eafbf02b8 100644 --- a/TopSpace/Login.js +++ b/TopSpace/Login.js @@ -40,7 +40,7 @@ function newLogin() { Auth0 = new auth0.WebAuth(parameters); userAuthorization = window.location.hash.substr(1); // What comes after the # on the URL. - + let sessionToken = window.localStorage.getItem('sessionToken'); if (sessionToken !== null && sessionToken !== "") { @@ -81,56 +81,136 @@ function newLogin() { // We store the token so we can identify the user window.localStorage.setItem('auth0Token', authResult.accessToken); - /* Now we connect to the users module to get the users alias, first, middle and last names. */ + /* Now we connect to the users and team modules + to get the users alias, first, middle and last names + as well as the user's teams and their team data. */ - const apolloClient = new Apollo.lib.ApolloClient({ - networkInterface: Apollo.lib.createNetworkInterface({ - /*uri: 'http://localhost:4000/graphql',*/ - uri: 'https://users-api.advancedalgos.net/graphql', - transportBatching: true, - }), - connectToDevTools: true, - }) + // To avoid race conditions, add asynchronous fetches to array + let fetchDataPromises = []; - const QUERY = Apollo.gql` - query($authId: String){ - userByAuthId (authId: $authId){ - id - referrerId - alias - firstName - middleName - lastName - bio - email - emailVerified - isDeveloper - isDataAnalyst - isTrader - avatarHandle - avatarChangeDate - sessionToken - role { - id - } - } - } - ` + const apolloClient = new Apollo.lib.ApolloClient({ + networkInterface: Apollo.lib.createNetworkInterface({ + /*uri: 'http://localhost:4000/graphql',*/ + uri: 'https://users-api.advancedalgos.net/graphql', + transportBatching: true, + }), + connectToDevTools: true, + }) - apolloClient.query({ - query: QUERY, - variables: { - authId: authId - } - }) - .then(response => { - console.log("apolloClient data", response); - let sessionToken = response.data.userByAuthId.sessionToken; - window.localStorage.setItem('sessionToken', sessionToken); - window.localStorage.setItem('loggedInUser', JSON.stringify(response.data.userByAuthId)); - window.location = "/index.html?" + sessionToken; - }) - .catch(error => console.error("apolloClient error", error)); + const QUERY = Apollo.gql` + query($authId: String){ + userByAuthId (authId: $authId){ + id + referrerId + alias + firstName + middleName + lastName + bio + email + emailVerified + isDeveloper + isDataAnalyst + isTrader + avatarHandle + avatarChangeDate + sessionToken + role { + id + } + } + } + ` + const getUser = () => { + return new Promise((resolve, reject) => { + apolloClient.query({ + query: QUERY, + variables: { + authId: authId + } + }) + .then(response => { + console.log("apolloClient data", response); + let sessionToken = response.data.userByAuthId.sessionToken; + window.localStorage.setItem('sessionToken', sessionToken); + window.localStorage.setItem('loggedInUser', JSON.stringify(response.data.userByAuthId)); + resolve({user: response.data.userByAuthId}) + }) + .catch(error => { + console.log("apolloClient error", error) + // reject (error) + }); + }); + } + + const networkInterfaceTeams = Apollo.lib.createNetworkInterface({ + // uri: 'http://localhost:4001/graphql', + uri: 'https://teams-api.advancedalgos.net/graphql' + }); + + networkInterfaceTeams.use([{ + applyMiddleware(req, next) { + req.options.headers = { + authorization: `Bearer ${authResult.accessToken}` + }; + next(); + } + }]); + + const apolloClientTeams = new Apollo.lib.ApolloClient({ + networkInterface: networkInterfaceTeams, + connectToDevTools: true, + }); + + const TEAM_BY_OWNER_QUERY = Apollo.gql` + query teamsByOwnerQuery($authId: String!) { + teamsByOwner(ownerId: $authId) { + id + name + slug + profile { + avatar + banner + description + motto + updatedAt + } + members { + member { + alias + } + } + } + } + ` + + const getTeamByOwner = () => { + return new Promise((resolve, reject) => { + apolloClientTeams.query({ + query: TEAM_BY_OWNER_QUERY, + variables: { authId: authId } + }) + .then(response => { + console.log("apolloClientTeam data", response); + window.localStorage.setItem('userTeams', JSON.stringify(response.data.teamsByOwner)); + resolve({teams: response.data.teamsByOwner}) + }) + .catch(error => { + console.log("apolloClientTeam error", error) + // reject (error) + }); + }) + } + + fetchDataPromises.push(getUser(), getTeamByOwner()); + + // When all asynchronous fetches resolve, refresh page or throw error. + Promise.all(fetchDataPromises).then(result => { + console.log('fetchDataPromises: ', result); + window.location = "/index.html?" + sessionToken; + }, err => { + console.error("fetchData error", err) + }); }); } @@ -148,6 +228,8 @@ function newLogin() { window.localStorage.setItem('sessionToken', ""); window.localStorage.setItem('loggedInUser', ""); + window.localStorage.setItem('userTeams', ""); + window.localStorage.setItem('accessToken', ""); window.location = "/index.html"; currentLabel = "Login / Signup"; @@ -168,6 +250,8 @@ function newLogin() { window.localStorage.setItem('sessionToken', ""); window.localStorage.setItem('loggedInUser', ""); + window.localStorage.setItem('userTeams', ""); + window.localStorage.setItem('accessToken', ""); window.location = "/index.html"; currentLabel = "Login / Signup"; } @@ -211,4 +295,4 @@ function newLogin() { browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)'; browserCanvasContext.fillText(label, point.x, point.y); } -} \ No newline at end of file +} diff --git a/server.js b/server.js index d315bec6b..8132104f8 100644 --- a/server.js +++ b/server.js @@ -51,7 +51,7 @@ const STORAGE = require('./Server/Storage'); let storage = STORAGE.newStorage(); let sessionManager; // This module have all authenticated active sessions. -let storageAccessManager; // This module manages the SAS for user to access the cloud storage from the browser. +let storageAccessManager; // This module manages the SAS for user to access the cloud storage from the browser. initialize(); @@ -94,7 +94,7 @@ function initialize() { ecosystem = pEcosystem; ecosystemObject = pEcosystemObject; - + storage.initialize(storageData, serverConfig) const CLOUD_SCRIPTS = require('./Server/CloudScripts'); @@ -200,7 +200,7 @@ function onBrowserRequest(request, response) { return; } - + switch (requestParameters[1]) { @@ -243,7 +243,7 @@ function onBrowserRequest(request, response) { ' {' + '\n' + ' plotter = newPlotterName();' + '\n' + ' }' + '\n' + - ' break;' + '\n' + '\n' + ' break;' + '\n' + '\n' let devTeams = ecosystemObject.devTeams; let hosts = ecosystemObject.hosts; @@ -399,7 +399,7 @@ function onBrowserRequest(request, response) { /* At this page we need to insert the configuration file for the whole system that we assamble before at the begining of this module - execution. So what we do is to load a template file with an insertion point where the configuration json is injected in. + execution. So what we do is to load a template file with an insertion point where the configuration json is injected in. */ @@ -415,9 +415,9 @@ function onBrowserRequest(request, response) { try { let fileContent = file.toString(); - let insertContent = JSON.stringify(ecosystemObject); + let insertContent = JSON.stringify(ecosystemObject); - fileContent = fileContent.replace('"@ecosystem.json@"', insertContent); + fileContent = fileContent.replace('"@ecosystem.json@"', insertContent); respondWithContent(fileContent, response); @@ -449,7 +449,7 @@ function onBrowserRequest(request, response) { respondWithFile('./CloudVM/' + filePath, response); } - break; + break; case "Exchange": // This means the Exchange folder. { @@ -466,7 +466,7 @@ function onBrowserRequest(request, response) { respondWithFile('./Exchange/' + filePath, response); } - break; + break; case "Images": // This means the Scripts folder. { @@ -494,7 +494,7 @@ function onBrowserRequest(request, response) { respondWithImage(path, response); } - break; + break; case "favicon.ico": // This means the Scripts folder. { @@ -502,7 +502,7 @@ function onBrowserRequest(request, response) { respondWithImage('./Images/' + 'favicon.ico', response); } - break; + break; case "BottomSpace": // This means the BottomSpace folder. { @@ -510,7 +510,7 @@ function onBrowserRequest(request, response) { respondWithFile('./BottomSpace/' + requestParameters[2], response); } - break; + break; case "TopSpace": // This means the TopSpace folder. { @@ -518,7 +518,7 @@ function onBrowserRequest(request, response) { respondWithFile('./TopSpace/' + requestParameters[2], response); } - break; + break; case "AABrowserAPI": // This means the Scripts folder. { @@ -599,7 +599,7 @@ function onBrowserRequest(request, response) { } } } - break; + break; case "Scripts": // This means the Scripts folder. { @@ -721,7 +721,7 @@ function onBrowserRequest(request, response) { } } - break; + break; case "ExchangeAPI": // This is trying to access this library functionality from the broser. { @@ -736,7 +736,7 @@ function onBrowserRequest(request, response) { assetA: "USDT", assetB: "BTC" }; - + const EXCHANGE_API = require('./Server/Exchange/ExchangeAPI'); let exchangeAPI = EXCHANGE_API.newExchangeAPI(botDisplayName, authToken); @@ -763,8 +763,8 @@ function onBrowserRequest(request, response) { } } } - - function callExchangeAPIMethod() { + + function callExchangeAPIMethod() { switch (requestParameters[3]) { case "getTicker": { @@ -791,7 +791,7 @@ function onBrowserRequest(request, response) { exchangeAPI.moveOrder(requestParameters[5], requestParameters[6], requestParameters[7], onExchangeResponse); break; } - + case "getPublicTradeHistory": { exchangeAPI.getPublicTradeHistory(global.MARKET, requestParameters[5], requestParameters[6], requestParameters[7], onExchangeResponse); break; @@ -801,7 +801,7 @@ function onBrowserRequest(request, response) { onExchangeResponse(global.DEFAULT_OK_RESPONSE); break; } - + } } @@ -830,8 +830,8 @@ function onBrowserRequest(request, response) { } } - break; - + break; + case "AACloud": // This means the cloud folder. { @@ -861,7 +861,7 @@ function onBrowserRequest(request, response) { respondWithContent("", response); } } - break; + break; case "Bots": // This means the cloud folder. { @@ -880,7 +880,7 @@ function onBrowserRequest(request, response) { path = requestParameters[5]; } - botScripts.getScript(devTeam, source, repo, path, onScriptReady) + botScripts.getScript(devTeam, source, repo, path, onScriptReady) break; } @@ -923,7 +923,7 @@ function onBrowserRequest(request, response) { } } - break; + break; case "Plotters": // This means the plotter folder, not to be confused with the Plotters script! { @@ -945,7 +945,7 @@ function onBrowserRequest(request, response) { } } - break; + break; case "PlotterPanels": // This means the PlotterPanels folder, not to be confused with the Plotter Panels scripts! { @@ -966,7 +966,7 @@ function onBrowserRequest(request, response) { } } - break; + break; case "Panels": { respondWithFile('./' + requestParameters[1] + '/' + requestParameters[2], response); @@ -1012,7 +1012,7 @@ function onBrowserRequest(request, response) { default: { homePage(); - } + } } function homePage() { @@ -1069,8 +1069,8 @@ function onBrowserRequest(request, response) { stringToInsert = stringToInsert.replace('@image@', devTeam.codeName + ".png"); stringToInsert = stringToInsert.replace('@id@', devTeam.codeName + ".png"); - let firstPart = fileContent.substring(0, fileContent.indexOf('') + 15); - let secondPart = fileContent.substring(fileContent.indexOf('') + 15); + let firstPart = fileContent.substring(0, fileContent.indexOf('') + 13); + let secondPart = fileContent.substring(fileContent.indexOf('') + 13); fileContent = firstPart + stringToInsert + secondPart; @@ -1204,7 +1204,7 @@ function respondWithFile(fileName, response) { //console.log("File Sent: " + fileName); // } - catch (err) { + catch (err) { console.log("[ERROR] server -> respondWithFile -> onFileRead -> File Not Found: " + fileName + " or Error = " + err); returnEmptyArray(); } @@ -1295,4 +1295,4 @@ function processPost(request, response, callback) { response.writeHead(405, { 'Content-Type': 'text/plain' }); response.end(); } -} \ No newline at end of file +}