diff --git a/backend/app_sdk/app_base.py b/backend/app_sdk/app_base.py index 1a311ee7..ae57b0d2 100644 --- a/backend/app_sdk/app_base.py +++ b/backend/app_sdk/app_base.py @@ -101,7 +101,7 @@ class AppBase: except requests.exceptions.ConnectionError as e: print("Connectionerror: %s" % e) - action_result["result"] = "Bad setup during startup: %d" % e + action_result["result"] = "Bad setup during startup: %s" % e self.send_result(action_result, headers, stream_path) return @@ -288,7 +288,7 @@ class AppBase: # Do stuff here. innervalue = parse_nested_param(data, maxDepth(data)-0) outervalue = parse_nested_param(data, maxDepth(data)-1) - print("INNER: ", outervalue) + print("INNER: ", innervalue) print("OUTER: ", outervalue) if outervalue != innervalue: @@ -710,7 +710,17 @@ class AppBase: continue #print(destinationvalue) - if not run_validation(sourcevalue, condition["condition"]["value"], destinationvalue): + # NEGATE + validation = run_validation(sourcevalue, condition["condition"]["value"], destinationvalue) + + # Configuration = negated because of WorkflowAppActionParam.. + try: + if condition["condition"]["configuration"]: + validation = not validation + except KeyError: + pass + + if not validation: self.logger.info("Failed condition check for %s %s %s." % (sourcevalue, condition["condition"]["value"], destinationvalue)) return False, "Failed condition: %s %s %s" % (sourcevalue, condition["condition"]["value"], destinationvalue) diff --git a/backend/go-app/codegen.go b/backend/go-app/codegen.go index 0aa12fe4..f620cc7f 100644 --- a/backend/go-app/codegen.go +++ b/backend/go-app/codegen.go @@ -398,7 +398,7 @@ func makePythoncode(swagger *openapi3.Swagger, name, url, method string, paramet verifyAddin, ) - log.Printf("%s", data) + //log.Printf("%s", data) return functionname, data } diff --git a/backend/go-app/main.go b/backend/go-app/main.go index 0b58ae5d..7004a6b5 100644 --- a/backend/go-app/main.go +++ b/backend/go-app/main.go @@ -662,7 +662,7 @@ func handleApiAuthentication(resp http.ResponseWriter, request *http.Request) (U if len(Userdata.Username) > 0 { return Userdata, nil } else { - return Userdata, errors.New("User is invalid") + return Userdata, errors.New(fmt.Sprintf("User is invalid - no username found: %#v", Userdata)) } } @@ -1605,8 +1605,11 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) { } // This is a long check to see if an inactive admin can access the site + parsedAdmin := "false" if !userInfo.Active { if userInfo.Role == "admin" { + parsedAdmin = "true" + ctx := context.Background() q := datastore.NewQuery("Users") var users []User @@ -1672,7 +1675,14 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) { Expires: expiration, }) - returnData := fmt.Sprintf(`{"success": true, "cookies": [{"key": "session_token", "value": "%s", "expiration": %d}]}`, userInfo.Session, expiration.Unix()) + returnData := fmt.Sprintf(` + { + "success": true, + "admin": %s, + "orgs": [{"name": "Shuffle", "id": "123", "role": "admin"}], + "selected_org": {"name": "Shuffle", "id": "123", "role": "admin"}, + "cookies": [{"key": "session_token", "value": "%s", "expiration": %d}] + }`, parsedAdmin, userInfo.Session, expiration.Unix()) resp.WriteHeader(200) resp.Write([]byte(returnData)) @@ -6134,7 +6144,7 @@ func handleAppHotload(location string) error { } //log.Printf("Reading app folder: %#v", dir) - err = iterateAppGithubFolders(fs, dir, "", "") + err = iterateAppGithubFolders(fs, dir, "", "", false) if err != nil { log.Printf("Err: %s", err) return err @@ -6345,7 +6355,7 @@ func runInit(ctx context.Context) { //iterateAppGithubFolders(fs, dir, "", "testing") // FIXME: Get all the apps? - iterateAppGithubFolders(fs, dir, "", "") + iterateAppGithubFolders(fs, dir, "", "", false) // Hotloads locally location := os.Getenv("APP_HOTLOAD_FOLDER") diff --git a/backend/go-app/walkoff.go b/backend/go-app/walkoff.go index 037c8500..da75a0be 100644 --- a/backend/go-app/walkoff.go +++ b/backend/go-app/walkoff.go @@ -94,6 +94,7 @@ type AuthenticationUsage struct { } // An app inside Shuffle +// Source string `json:"source" datastore:"soure" yaml:"source"` - downloadlocation type WorkflowApp struct { Name string `json:"name" yaml:"name" required:true datastore:"name"` IsValid bool `json:"is_valid" yaml:"is_valid" required:true datastore:"is_valid"` @@ -4221,9 +4222,10 @@ func loadSpecificApps(resp http.ResponseWriter, request *http.Request) { // Field1 & 2 can be a lot of things.. type tmpStruct struct { - URL string `json:"url"` - Field1 string `json:"field_1"` - Field2 string `json:"field_2"` + URL string `json:"url"` + Field1 string `json:"field_1"` + Field2 string `json:"field_2"` + ForceUpdate bool `json:"force_update"` } //log.Printf("Body: %s", string(body)) @@ -4265,7 +4267,13 @@ func loadSpecificApps(resp http.ResponseWriter, request *http.Request) { log.Printf("FAiled reading folder: %s", err) } _ = r - iterateAppGithubFolders(fs, dir, "", "") + + if tmpBody.ForceUpdate { + log.Printf("Running with force update!") + } else { + log.Printf("Updating apps with updates") + } + iterateAppGithubFolders(fs, dir, "", "", tmpBody.ForceUpdate) } else if strings.Contains(tmpBody.URL, "s3") { //https://docs.aws.amazon.com/sdk-for-go/api/service/s3/ @@ -4490,8 +4498,13 @@ func iterateWorkflowGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra } // Onlyname is used to -func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra string, onlyname string) error { +func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra string, onlyname string, forceUpdate bool) error { var err error + + allapps := []WorkflowApp{} + + // It's here to prevent getting them in every iteration + ctx := context.Background() for _, file := range dir { if len(onlyname) > 0 && file.Name() != onlyname { continue @@ -4508,7 +4521,7 @@ func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra strin } // Go routine? Hmm, this can be super quick I guess - err = iterateAppGithubFolders(fs, dir, tmpExtra, "") + err = iterateAppGithubFolders(fs, dir, tmpExtra, "", forceUpdate) if err != nil { log.Printf("Error reading folder: %s", err) continue @@ -4591,12 +4604,12 @@ func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra strin fmt.Sprintf("%s:%s_%s", baseDockerName, newName, workflowapp.AppVersion), } - ctx := context.Background() - allapps, err := getAllWorkflowApps(ctx) - if err != nil { - log.Printf("Failed getting apps to verify: %s", err) - continue - //return err + if len(allapps) == 0 { + allapps, err = getAllWorkflowApps(ctx) + if err != nil { + log.Printf("Failed getting apps to verify: %s", err) + continue + } } // Make an option to override existing apps? @@ -4607,7 +4620,7 @@ func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra strin if app.Name == workflowapp.Name && app.AppVersion == workflowapp.AppVersion { // FIXME: Check if there's a new APP_SDK as well. // Skip this check if app_sdk is new. - if app.Hash == md5 && app.Hash != "" { + if app.Hash == md5 && app.Hash != "" && !forceUpdate { skip = true break } @@ -4617,7 +4630,7 @@ func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra strin } } - if skip { + if skip && !forceUpdate { continue } @@ -4677,6 +4690,7 @@ func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra strin if len(removeApps) > 0 { for _, item := range removeApps { + log.Printf("Removing duplicate: %s", item) err = DeleteKey(ctx, "workflowapp", item) if err != nil { log.Printf("Failed deleting %s", item) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 276ecded..6f78e4b1 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,6 +1,6 @@ { "name": "shuffler", - "version": "0.3.0", + "version": "0.6.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -3733,9 +3733,9 @@ "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" }, "@types/node": { - "version": "14.0.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.13.tgz", - "integrity": "sha512-rouEWBImiRaSJsVA+ITTFM6ZxibuAlTuNOCyxVbwreu6k6+ujs7DfnU9o+PShFhET78pMBl3eH+AGSI5eOTkPA==" + "version": "14.0.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.24.tgz", + "integrity": "sha512-btt/oNOiDWcSuI721MdL8VQGnjsKjlTMdrKyTcLCKeQp/n4AAMFJ961wMbp+09y8WuGPClDEv07RIItdXKIXAA==" }, "@types/object-assign": { "version": "4.0.30", @@ -3748,9 +3748,9 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" }, "@types/prop-types": { - "version": "15.7.1", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.1.tgz", - "integrity": "sha512-CFzn9idOEpHrgdw8JsoTkaDDyRWk1jrzIV8djzcgpq0y9tG4B4lFT+Nxh52DVpDXV+n4+NPNv7M1Dj5uMp6XFg==" + "version": "15.7.3", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", + "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==" }, "@types/q": { "version": "1.5.4", @@ -3758,9 +3758,9 @@ "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==" }, "@types/react": { - "version": "16.8.20", - "resolved": "https://registry.npmjs.org/@types/react/-/react-16.8.20.tgz", - "integrity": "sha512-ZLmI+ubSJpfUIlQuULDDrdyuFQORBuGOvNnMue8HeA0GVrAJbWtZQhcBvnBPNRBI/GrfSfrKPFhthzC2SLEtLQ==", + "version": "16.9.43", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.43.tgz", + "integrity": "sha512-PxshAFcnJqIWYpJbLPriClH53Z2WlJcVZE+NP2etUtWQs2s7yIMj3/LDKZT/5CHJ/F62iyjVCDu2H3jHEXIxSg==", "requires": { "@types/prop-types": "*", "csstype": "^2.2.0" @@ -11944,9 +11944,9 @@ } }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" }, "lodash._reinterpolate": { "version": "3.0.0", diff --git a/frontend/src/App.js b/frontend/src/App.js deleted file mode 100644 index c162b774..00000000 --- a/frontend/src/App.js +++ /dev/null @@ -1,169 +0,0 @@ -import React, {useState, useEffect} from 'react'; - -import {Route} from 'react-router'; -import {BrowserRouter} from 'react-router-dom'; -import { CookiesProvider } from 'react-cookie'; -import { useCookies } from 'react-cookie'; - -import EditSchedule from "./EditSchedule"; -import Schedules from "./Schedules"; -import Webhooks from "./Webhooks"; -import Workflows from "./Workflows"; -import EditWebhook from "./EditWebhook"; -import AngularWorkflow from "./AngularWorkflow"; -import ForgotPassword from "./ForgotPassword"; -import ForgotPasswordLink from "./ForgotPasswordLink"; - -import Header from './Header'; -import Apps from './Apps'; -import AppCreator from './AppCreator'; -import Contact from './Contact'; -import Oauth2 from './Oauth2'; -import About from "./About"; -import Post from "./Post"; -import Dashboard from "./Dashboard"; -import AdminSetup from "./AdminSetup"; -import Admin from "./Admin"; -import Docs from "./Docs"; -import RegisterLink from "./RegisterLink"; -import LandingPage from "./Landingpage"; -import LandingPageNew from "./LandingpageNew"; -import LoginPage from "./LoginPage"; -import SettingsPage from "./SettingsPage"; - -import MuiThemeProvider from '@material-ui/core/styles/MuiThemeProvider'; -import { createMuiTheme } from '@material-ui/core/styles'; - -import AlertTemplate from "react-alert-template-basic"; -import { positions, Provider } from "react-alert"; - -// Production - backend proxy forwarding in nginx -var globalUrl = window.location.origin - -// CORS used for testing purposes. Should only happen with specific port and http -if (window.location.protocol == "http:" && window.location.port === "3000") { - globalUrl = "http://localhost:5001" -} - -const surfaceColor = "#27292D" -const inputColor = "#383B40" - -const theme = createMuiTheme({ - palette: { - primary: { - main: "#f85a3e" - }, - secondary: { - main: '#e8eaf6', - }, - }, - typography: { - useNextVariants: true - }, - overrides: { - MuiMenu: { - list: { - backgroundColor: inputColor, - }, - }, - }, -}); - - -// FIXME - set client side cookies -const App = (message, props) => { - const [userdata, setUserData] = useState({}); - //const [homePage, ] = useState(true); - const [cookies, setCookie, removeCookie] = useCookies([]); - const [isLoggedIn, setIsLoggedIn] = useState(false); - const [dataset, setDataset] = useState(false); - const [isLoaded, setIsLoaded] = useState(false); - - useEffect(() => { - if (dataset === false) { - checkLogin() - setDataset(true) - }}) - - if (isLoaded && !isLoggedIn && (!window.location.pathname.startsWith("/login") && (!window.location.pathname.startsWith("/docs") && (!window.location.pathname.startsWith("/adminsetup"))))) { - window.location = "/login" - } - - const checkLogin = () => { - var baseurl = globalUrl - fetch(baseurl+"/api/v1/users/getinfo", { - credentials: "include", - headers: { - 'Content-Type': 'application/json', - }, - }) - .then(response => response.json()) - .then(responseJson => { - if (responseJson.success === true) { - setUserData(responseJson) - setIsLoggedIn(true) - - // Updating cookie every request - for (var key in responseJson["cookies"]) { - setCookie(responseJson["cookies"][key].key, responseJson["cookies"][key].value, {path: "/"}) - } - } - setIsLoaded(true) - }) - .catch(error => { - setIsLoaded(true) - }); - } - - // Dumb for content load (per now), but good for making the site not suddenly reload parts (ajax thingies) - - const options = { - timeout: 5000, - position: positions.BOTTOM_CENTER - }; - - const includedData = window.location.pathname === "/home" || window.location.pathname === "/features" ? -
- } /> -
: -
-
- } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - {window.location.pathname = "/docs/about"}} /> - {window.location.pathname = "/login"}} /> -
- - //
- // backgroundColor: "#213243", - // This is a mess hahahah - return ( - - - - - {includedData} - - - - - ); -}; - -export default App; - diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx new file mode 100644 index 00000000..1e6a0fc3 --- /dev/null +++ b/frontend/src/App.jsx @@ -0,0 +1,163 @@ +import React, { useState, useEffect } from 'react'; + +import { Route } from 'react-router'; +import { BrowserRouter } from 'react-router-dom'; +import { CookiesProvider } from 'react-cookie'; +import { useCookies } from 'react-cookie'; + +import EditSchedule from "./views/EditSchedule"; +import Schedules from "./views/Schedules"; +import Webhooks from "./views/Webhooks"; +import Workflows from "./views/Workflows"; +import EditWebhook from "./views/EditWebhook"; +import AngularWorkflow from "./views/AngularWorkflow"; + +import Header from './components/Header'; +import Apps from './views/Apps'; +import AppCreator from './views/AppCreator'; +import Contact from './views/Contact'; +import Oauth2 from './views/Oauth2'; + +import Dashboard from "./views/Dashboard"; +import AdminSetup from "./views/AdminSetup"; +import Admin from "./views/Admin"; +import Docs from "./views/Docs"; + +import LandingPageNew from "./views/LandingpageNew"; +import LoginPage from "./views/LoginPage"; +import SettingsPage from "./views/SettingsPage"; + +import { createMuiTheme, MuiThemeProvider } from '@material-ui/core/styles'; + +import AlertTemplate from "react-alert-template-basic"; +import { positions, Provider } from "react-alert"; + +// Production - backend proxy forwarding in nginx +var globalUrl = window.location.origin + +// CORS used for testing purposes. Should only happen with specific port and http +if (window.location.protocol == "http:" && window.location.port === "3000") { + globalUrl = "http://localhost:5001" +} + +const theme = createMuiTheme({ + palette: { + primary: { + main: "#f85a3e" + }, + secondary: { + main: '#e8eaf6', + }, + surfaceColor: "#27292d", + inputColor: "#383B40" + }, + typography: { + useNextVariants: true + }, + overrides: { + MuiMenu: { + list: { + backgroundColor: "#383B40", + }, + }, + }, +}); + + +// FIXME - set client side cookies +const App = (message, props) => { + const [userdata, setUserData] = useState({}); + //const [homePage, ] = useState(true); + const [cookies, setCookie, removeCookie] = useCookies([]); + const [isLoggedIn, setIsLoggedIn] = useState(false); + const [dataset, setDataset] = useState(false); + const [isLoaded, setIsLoaded] = useState(false); + + useEffect(() => { + if (dataset === false) { + checkLogin() + setDataset(true) + } + }) + + if (isLoaded && !isLoggedIn && (!window.location.pathname.startsWith("/login") && (!window.location.pathname.startsWith("/docs") && (!window.location.pathname.startsWith("/adminsetup"))))) { + window.location = "/login" + } + + const checkLogin = () => { + var baseurl = globalUrl + fetch(baseurl + "/api/v1/users/getinfo", { + credentials: "include", + headers: { + 'Content-Type': 'application/json', + }, + }) + .then(response => response.json()) + .then(responseJson => { + if (responseJson.success === true) { + setUserData(responseJson) + setIsLoggedIn(true) + + // Updating cookie every request + for (var key in responseJson["cookies"]) { + setCookie(responseJson["cookies"][key].key, responseJson["cookies"][key].value, { path: "/" }) + } + } + setIsLoaded(true) + }) + .catch(error => { + setIsLoaded(true) + }); + } + + // Dumb for content load (per now), but good for making the site not suddenly reload parts (ajax thingies) + + const options = { + timeout: 5000, + position: positions.BOTTOM_CENTER + }; + + const includedData = window.location.pathname === "/home" || window.location.pathname === "/features" ? +
+ } /> +
: +
+
+ } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + { window.location.pathname = "/docs/about" }} /> + { window.location.pathname = "/login" }} /> +
+ + //
+ // backgroundColor: "#213243", + // This is a mess hahahah + return ( + + + + + {includedData} + + + + + ); +}; + +export default App; diff --git a/frontend/src/Flows.js b/frontend/src/Flows.js deleted file mode 100644 index aa1a35a3..00000000 --- a/frontend/src/Flows.js +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react'; - -const Flows = () => { - return ( -
-

Flows

- -

- Built to suit any organization -

- -

- WAT -

- -

-

- -

- -
- ) -} - -export default Flows; diff --git a/frontend/src/Hookpost.js b/frontend/src/Hookpost.js deleted file mode 100644 index 566a26d4..00000000 --- a/frontend/src/Hookpost.js +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react'; - -const Hooks = () => { - return ( -
-

Hooks

- -

- Built to suit any organization -

- -

- WAT -

- -

-

- -

- -
- ) -} - -export default Hooks; diff --git a/frontend/src/Schedulespost.js b/frontend/src/Schedulespost.js deleted file mode 100644 index 102144e7..00000000 --- a/frontend/src/Schedulespost.js +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react'; - -const Schedules = () => { - return ( -
-

Schedules

- -

- Built to suit any organization -

- -

- WAT -

- -

-

- -

- -
- ) -} - -export default Schedules; diff --git a/frontend/src/appdata.js b/frontend/src/__test__/appdata.js similarity index 100% rename from frontend/src/appdata.js rename to frontend/src/__test__/appdata.js diff --git a/frontend/src/environmentdata.js b/frontend/src/__test__/environmentdata.js similarity index 100% rename from frontend/src/environmentdata.js rename to frontend/src/__test__/environmentdata.js diff --git a/frontend/src/scheduledata.js b/frontend/src/__test__/scheduledata.js similarity index 100% rename from frontend/src/scheduledata.js rename to frontend/src/__test__/scheduledata.js diff --git a/frontend/src/webhookdata.js b/frontend/src/__test__/webhookdata.js similarity index 100% rename from frontend/src/webhookdata.js rename to frontend/src/__test__/webhookdata.js diff --git a/frontend/src/workflowdata.js b/frontend/src/__test__/workflowdata.js similarity index 100% rename from frontend/src/workflowdata.js rename to frontend/src/__test__/workflowdata.js diff --git a/frontend/src/AlertPopup.js b/frontend/src/components/AlertPopup.js similarity index 100% rename from frontend/src/AlertPopup.js rename to frontend/src/components/AlertPopup.js diff --git a/frontend/src/AlertTemplate.js b/frontend/src/components/AlertTemplate.js similarity index 100% rename from frontend/src/AlertTemplate.js rename to frontend/src/components/AlertTemplate.js diff --git a/frontend/src/FooterNew.js b/frontend/src/components/FooterNew.js similarity index 100% rename from frontend/src/FooterNew.js rename to frontend/src/components/FooterNew.js diff --git a/frontend/src/Header.js b/frontend/src/components/Header.js similarity index 90% rename from frontend/src/Header.js rename to frontend/src/components/Header.js index 7a01cb53..7495d06d 100644 --- a/frontend/src/Header.js +++ b/frontend/src/components/Header.js @@ -5,19 +5,22 @@ import {Link} from 'react-router-dom'; import List from '@material-ui/core/List'; import ListItem from '@material-ui/core/ListItem'; - +import MenuItem from '@material-ui/core/MenuItem'; +import Select from '@material-ui/core/Select'; import Button from '@material-ui/core/Button'; import HomeIcon from '@material-ui/icons/Home'; import PolymerIcon from '@material-ui/icons/Polymer'; import AppsIcon from '@material-ui/icons/Apps'; import DescriptionIcon from '@material-ui/icons/Description'; import Grid from '@material-ui/core/Grid'; +import { useTheme } from '@material-ui/core/styles'; const hoverColor = "#f85a3e" const hoverOutColor = "#e8eaf6" const Header = props => { - const { globalUrl, isLoggedIn, removeCookie, homePage, isLoaded } = props; + const { globalUrl, isLoggedIn, removeCookie, homePage, isLoaded, userdata } = props; + const theme = useTheme(); const [HomeHoverColor, setHomeHoverColor] = useState(hoverOutColor); const [SoarHoverColor, setSoarHoverColor] = useState(hoverOutColor); @@ -100,7 +103,7 @@ const Header = props => { // Handle top bar or something - const loginTextBrowser = !isLoggedIn ? + const loginTextBrowser = !isLoggedIn ?
@@ -192,6 +195,32 @@ const Header = props => { + {userdata === undefined || userdata.orgs.length <= 1 ? null : + + + + } +
@@ -287,7 +316,7 @@ const Header = props => {
{loadedCheck}
- ); -}; + ) +} export default Header; diff --git a/frontend/src/LoginPopup.js b/frontend/src/components/LoginPopup.js similarity index 100% rename from frontend/src/LoginPopup.js rename to frontend/src/components/LoginPopup.js diff --git a/frontend/src/SettingsPopup.js b/frontend/src/components/SettingsPopup.js similarity index 100% rename from frontend/src/SettingsPopup.js rename to frontend/src/components/SettingsPopup.js diff --git a/frontend/src/About.js b/frontend/src/views/About.jsx similarity index 85% rename from frontend/src/About.js rename to frontend/src/views/About.jsx index 913eff3d..9c4044f9 100644 --- a/frontend/src/About.js +++ b/frontend/src/views/About.jsx @@ -1,7 +1,7 @@ import React from 'react'; const hrefStyle = { - color: "#f85a3e", + color: "#f85a3e", textDecoration: "none" } @@ -12,17 +12,17 @@ const About = () => {

About

- Endao was started as a project in late 2018 as a free service to analyze APK (and soon IPA) files for vulnerabilities. The project was started after I, + Endao was started as a project in late 2018 as a free service to analyze APK (and soon IPA) files for vulnerabilities. The project was started after I, @frikkylikeme , found multiple vulnerabilities in IoT devices based purely on their apps. As I wanted to learn more about these kind of vulnerabilities, I looked for solutions that work for my purpose, but didn't find any good, free and easy to use service - hence this site was born.

- My personal goal has and will always be to make the internet safer. As the IoT sphere grows, I want to be able to add ways of finding possible vulnerabilities fast to this website. This will hopefully include blogposts when I get around to it, as well as actual implementations. The vulnerability discovery field is in no way new, but I'll try my best to add whatever I can to it. As a disclaimer, I'm an "Ops" person, and I had never done frontend before creating this site. This is as much of a learning project within web development as it is in vulnerability discovery. + My personal goal has and will always be to make the internet safer. As the IoT sphere grows, I want to be able to add ways of finding possible vulnerabilities fast to this website. This will hopefully include blogposts when I get around to it, as well as actual implementations. The vulnerability discovery field is in no way new, but I'll try my best to add whatever I can to it. As a disclaimer, I'm an "Ops" person, and I had never done frontend before creating this site. This is as much of a learning project within web development as it is in vulnerability discovery.

- This site currently uses the following projects + This site currently uses the following projects

{datafield} @@ -3553,11 +3548,21 @@ const AngularWorkflow = (props) => {
Condition
+ + +
-
- { setVariableAnchorEl(null) }} key={"less than"}>less than - -
+
@@ -4774,7 +4778,7 @@ const AngularWorkflow = (props) => { Exit on Error + label={
Exit on Error
} control={ { workflow.configuration.exit_on_error = !workflow.configuration.exit_on_error @@ -4786,7 +4790,7 @@ const AngularWorkflow = (props) => { /> Start from top + label={
Start from top
} control={ { workflow.configuration.start_from_top = !workflow.configuration.start_from_top @@ -5114,7 +5118,7 @@ const AngularWorkflow = (props) => {

Executing Workflow

Show failed / skipped actions + label={
Show failed / skipped actions
} control={ {setShowSkippedActions(!showSkippedActions)}} /> } diff --git a/frontend/src/AppCreator.js b/frontend/src/views/AppCreator.jsx similarity index 100% rename from frontend/src/AppCreator.js rename to frontend/src/views/AppCreator.jsx diff --git a/frontend/src/Apps.js b/frontend/src/views/Apps.jsx similarity index 97% rename from frontend/src/Apps.js rename to frontend/src/views/Apps.jsx index 0d1d7263..35bef2d4 100644 --- a/frontend/src/Apps.js +++ b/frontend/src/views/Apps.jsx @@ -286,7 +286,7 @@ const Apps = (props) => { } return ( - { + { if (selectedApp.id !== data.id) { setSelectedApp(data) console.log(data) @@ -515,7 +515,7 @@ const Apps = (props) => { newActionname = newActionname.replace("_", " ") newActionname = newActionname.charAt(0).toUpperCase()+newActionname.substring(1) return ( - + {newActionname} @@ -540,7 +540,7 @@ const Apps = (props) => { const circleSize = 10 return ( - +
{data.name} @@ -654,7 +654,7 @@ const Apps = (props) => { {isLoading ? : null} Search OpenAPI
+ label={
Search OpenAPI
} control={ { handleSearchChange("") setSearchBackend(!searchBackend)} @@ -743,7 +743,7 @@ const Apps = (props) => { null // Load data e.g. from github - const getSpecificApps = (url) => { + const getSpecificApps = (url, forceUpdate) => { setValidation(true) setIsLoading(true) @@ -761,6 +761,8 @@ const Apps = (props) => { parsedData["field_2"] = field2 } + parsedData["force_update"] = forceUpdate + alert.success("Getting specific apps from your URL.") var cors = "cors" fetch(globalUrl+"/api/v1/apps/get_existing", { @@ -977,8 +979,8 @@ const Apps = (props) => { window.location.href = "/apps/new?id="+appValidation } - const handleGithubValidation = () => { - getSpecificApps(openApi) + const handleGithubValidation = (forceUpdate) => { + getSpecificApps(openApi, forceUpdate) setLoadAppsModalOpen(false) } @@ -1034,7 +1036,7 @@ const Apps = (props) => { >
- Load from github repo + Load from github repo
@@ -1098,7 +1100,12 @@ const Apps = (props) => { Cancel + diff --git a/frontend/src/Contact.js b/frontend/src/views/Contact.jsx similarity index 54% rename from frontend/src/Contact.js rename to frontend/src/views/Contact.jsx index 97cf84e6..5a34382c 100644 --- a/frontend/src/Contact.js +++ b/frontend/src/views/Contact.jsx @@ -1,11 +1,13 @@ -import React, {useState} from 'react'; -import {BrowserView, MobileView} from "react-device-detect"; +import React, { useState } from 'react'; +import { BrowserView, MobileView } from "react-device-detect"; import Paper from '@material-ui/core/Paper'; import Button from '@material-ui/core/Button'; import TextField from '@material-ui/core/TextField'; +import { useTheme } from '@material-ui/core/styles'; + const bodyDivStyle = { margin: "auto", textAlign: "center", @@ -13,11 +15,11 @@ const bodyDivStyle = { } - - // Should be different if logged in :| const Contact = (props) => { - const { globalUrl, isLoaded, surfaceColor, inputColor } = props; + const { globalUrl, isLoaded } = props; + + const theme = useTheme(); const boxStyle = { flex: "1", @@ -27,24 +29,24 @@ const Contact = (props) => { paddingRight: "30px", paddingBottom: "30px", paddingTop: "30px", - backgroundColor: surfaceColor, - display: "flex", + backgroundColor: theme.palette.surfaceColor, + display: "flex", flexDirection: "column" } - + const bodyTextStyle = { - color: "#ffffff", + color: "#ffffff", } - const [firstname, setFirstname] = useState(""); - const [lastname, setLastname] = useState(""); - const [title, setTitle] = useState(""); - const [companyname, setCompanyname] = useState(""); - const [email, setEmail] = useState(""); - const [phone, setPhone] = useState(""); - const [message, setMessage] = useState(""); + const [firstname, setFirstname] = useState(""); + const [lastname, setLastname] = useState(""); + const [title, setTitle] = useState(""); + const [companyname, setCompanyname] = useState(""); + const [email, setEmail] = useState(""); + const [phone, setPhone] = useState(""); + const [message, setMessage] = useState(""); - const [formMessage, setFormMessage] = useState(""); + const [formMessage, setFormMessage] = useState(""); const submitContact = () => { const data = { @@ -58,43 +60,43 @@ const Contact = (props) => { } console.log(data) - fetch(globalUrl+"/api/v1/contact", { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(data), - }) - .then(response => response.json()) - .then(response => { - if (response.success === true) { - setFormMessage(response.message) - } else { - setFormMessage("Something went wrong. Please contact frikky@shuffler.io.") - } - console.log(response) - }) - .catch(error => { - console.log(error) - }); + fetch(globalUrl + "/api/v1/contact", { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(data), + }) + .then(response => response.json()) + .then(response => { + if (response.success === true) { + setFormMessage(response.message) + } else { + setFormMessage("Something went wrong. Please contact frikky@shuffler.io.") + } + console.log(response) + }) + .catch(error => { + console.log(error) + }); } // Random names for type & autoComplete. Didn't research :^) - const landingpageDataBrowser = + const landingpageDataBrowser =
-

Contact us

+

Contact us

Lets talk!

-
+

Contact Details

-
+
{ fullWidth={true} placeholder="First Name" type="firstname" - id="standard-required" + id="standard-required" autoComplete="firstname" margin="normal" variant="outlined" - onChange={e => setFirstname(e.target.value)} + onChange={e => setFirstname(e.target.value)} /> { fullWidth={true} placeholder="Last Name" type="lastname" - id="standard" + id="standard" autoComplete="lastname" margin="normal" variant="outlined" - onChange={e => setLastname(e.target.value)} + onChange={e => setLastname(e.target.value)} />
-
+
{ fullWidth={true} placeholder="Job Title" type="jobtitle" - id="standard-required" + id="standard-required" autoComplete="jobtitle" margin="normal" variant="outlined" - onChange={e => setTitle(e.target.value)} + onChange={e => setTitle(e.target.value)} /> { fullWidth={true} type="companyname" placeholder="Company Name" - id="standard-required" + id="standard-required" autoComplete="companyname" margin="normal" variant="outlined" - onChange={e => setCompanyname(e.target.value)} + onChange={e => setCompanyname(e.target.value)} />
-
+
{ fullWidth={true} placeholder="Email" type="email" - id="standard-required" + id="standard-required" autoComplete="email" margin="normal" variant="outlined" - onChange={e => setEmail(e.target.value)} + onChange={e => setEmail(e.target.value)} /> { fullWidth={true} type="phone" placeholder="Phone number" - id="standard-required" + id="standard-required" autoComplete="phone" margin="normal" variant="outlined" - onChange={e => setPhone(e.target.value)} + onChange={e => setPhone(e.target.value)} />
-
+

Message

-
+
setMessage(e.target.value)} + onChange={e => setMessage(e.target.value)} />

{formMessage}

- const landingpageDataMobile = -
-
-

Contact us

+ const landingpageDataMobile = +
+
+

Contact us

Lets talk!

-
+

Contact Details

-
+
{ fullWidth={true} placeholder="Name" type="firstname" - id="standard-required" + id="standard-required" autoComplete="firstname" margin="normal" variant="outlined" - onChange={e => setFirstname(e.target.value)} + onChange={e => setFirstname(e.target.value)} />
-
+
{ fullWidth={true} placeholder="Email" type="email" - id="standard-required" + id="standard-required" autoComplete="email" margin="normal" variant="outlined" - onChange={e => setEmail(e.target.value)} + onChange={e => setEmail(e.target.value)} />
-
+

Message

-
+
{ id="filled-multiline-static" margin="normal" variant="outlined" - onChange={e => setMessage(e.target.value)} + onChange={e => setMessage(e.target.value)} />

{formMessage}

@@ -321,7 +323,7 @@ const Contact = (props) => {
- const loadedCheck = isLoaded ? + const loadedCheck = isLoaded ?
{landingpageDataBrowser}
@@ -334,7 +336,7 @@ const Contact = (props) => {
- return( + return (
{loadedCheck}
diff --git a/frontend/src/Dashboard.js b/frontend/src/views/Dashboard.jsx similarity index 99% rename from frontend/src/Dashboard.js rename to frontend/src/views/Dashboard.jsx index f450e99e..3ffb560e 100644 --- a/frontend/src/Dashboard.js +++ b/frontend/src/views/Dashboard.jsx @@ -35,7 +35,7 @@ import { chartExample2, chartExample3, chartExample4 -} from "./charts.js"; +} from "../charts.js"; // This is the start of a dashboard that can be used. // What data do we fill in here? Idk diff --git a/frontend/src/Docs.js b/frontend/src/views/Docs.jsx similarity index 100% rename from frontend/src/Docs.js rename to frontend/src/views/Docs.jsx diff --git a/frontend/src/EditSchedule.js b/frontend/src/views/EditSchedule.jsx similarity index 99% rename from frontend/src/EditSchedule.js rename to frontend/src/views/EditSchedule.jsx index 0c588172..c47453e8 100644 --- a/frontend/src/EditSchedule.js +++ b/frontend/src/views/EditSchedule.jsx @@ -34,9 +34,6 @@ import DeleteIcon from '@material-ui/icons/Delete'; import Downshift from 'downshift'; import deburr from 'lodash/deburr'; -//import appdata from './appdata'; - - const EditSchedule = (props) => { const { globalUrl } = props; diff --git a/frontend/src/EditWebhook.js b/frontend/src/views/EditWebhook.jsx similarity index 98% rename from frontend/src/EditWebhook.js rename to frontend/src/views/EditWebhook.jsx index 6653cb5a..ba42a58b 100644 --- a/frontend/src/EditWebhook.js +++ b/frontend/src/views/EditWebhook.jsx @@ -6,8 +6,8 @@ import Divider from '@material-ui/core/Divider'; import Select from '@material-ui/core/Select'; import MenuItem from '@material-ui/core/MenuItem'; -import WebhookImage from './assets/img/webhook.png'; -import KafkaImage from './assets/img/kafka.png'; +import WebhookImage from '../assets/img/webhook.png'; +import KafkaImage from '../assets/img/kafka.png'; import EditWorkflow from "./EditWorkflow"; diff --git a/frontend/src/EditWorkflow.js b/frontend/src/views/EditWorkflow.jsx similarity index 100% rename from frontend/src/EditWorkflow.js rename to frontend/src/views/EditWorkflow.jsx diff --git a/frontend/src/ForgotPassword.js b/frontend/src/views/ForgotPassword.jsx similarity index 100% rename from frontend/src/ForgotPassword.js rename to frontend/src/views/ForgotPassword.jsx diff --git a/frontend/src/ForgotPasswordLink.js b/frontend/src/views/ForgotPasswordLink.jsx similarity index 100% rename from frontend/src/ForgotPasswordLink.js rename to frontend/src/views/ForgotPasswordLink.jsx diff --git a/frontend/src/Landingpage.js b/frontend/src/views/Landingpage.jsx similarity index 100% rename from frontend/src/Landingpage.js rename to frontend/src/views/Landingpage.jsx diff --git a/frontend/src/LandingpageLoggedin.js b/frontend/src/views/LandingpageLoggedin.jsx similarity index 100% rename from frontend/src/LandingpageLoggedin.js rename to frontend/src/views/LandingpageLoggedin.jsx diff --git a/frontend/src/LandingpageNew.js b/frontend/src/views/LandingpageNew.jsx similarity index 100% rename from frontend/src/LandingpageNew.js rename to frontend/src/views/LandingpageNew.jsx diff --git a/frontend/src/LoginPage.js b/frontend/src/views/LoginPage.jsx similarity index 55% rename from frontend/src/LoginPage.js rename to frontend/src/views/LoginPage.jsx index 49e22f55..6ed887f3 100644 --- a/frontend/src/LoginPage.js +++ b/frontend/src/views/LoginPage.jsx @@ -1,13 +1,15 @@ /* eslint-disable react/no-multi-comp */ -import React, {useState} from 'react'; +import React, { useState } from 'react'; import { makeStyles } from '@material-ui/styles'; import TextField from '@material-ui/core/TextField'; import Button from '@material-ui/core/Button'; import Paper from '@material-ui/core/Paper'; +import { useTheme } from '@material-ui/core/styles'; + const hrefStyle = { - color: "white", + color: "white", textDecoration: "none" } @@ -17,16 +19,6 @@ const bodyDivStyle = { width: "500px", } -const surfaceColor = "#27292D" -const inputColor = "#383B40" - -const boxStyle = { - paddingLeft: "30px", - paddingRight: "30px", - paddingBottom: "30px", - paddingTop: "30px", - backgroundColor: surfaceColor, -} const useStyles = makeStyles({ notchedOutline: { @@ -35,12 +27,14 @@ const useStyles = makeStyles({ }); const LoginDialog = props => { - const { globalUrl, isLoaded, isLoggedIn, setIsLoggedIn, setCookie, register } = props; + const theme = useTheme(); + + const { globalUrl, isLoaded, isLoggedIn, setIsLoggedIn, setCookie, register } = props; const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const [firstRequest, setFirstRequest] = useState(true); - // Used to swap from login to register. True = login, false = register + // Used to swap from login to register. True = login, false = register const classes = useStyles(); // Error messages etc @@ -51,32 +45,32 @@ const LoginDialog = props => { } if (isLoggedIn === true) { - window.location.pathname = "/workflows" + window.location.pathname = "/workflows" } const checkAdmin = () => { - const url = globalUrl+'/api/v1/checkusers'; + const url = globalUrl + '/api/v1/checkusers'; fetch(url, { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - }, + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, }) - .then(response => - response.json().then(responseJson => { - if (responseJson["success"] === false) { - setLoginInfo(responseJson["reason"]) - } else { - if (responseJson.reason === "stay") { - window.location.pathname = "/adminsetup" + .then(response => + response.json().then(responseJson => { + if (responseJson["success"] === false) { + setLoginInfo(responseJson["reason"]) + } else { + if (responseJson.reason === "stay") { + window.location.pathname = "/adminsetup" + } } - } - }), - ) - .catch(error => { - setLoginInfo("Error in userdata: ", error) - }) + }), + ) + .catch(error => { + setLoginInfo("Error in userdata: ", error) + }) } if (firstRequest) { @@ -89,41 +83,41 @@ const LoginDialog = props => { // FIXME - add some check here ROFL // Just use this one? - var data = {"username": username, "password": password} + var data = { "username": username, "password": password } var baseurl = globalUrl if (register) { - var url = baseurl+'/api/v1/users/login'; + var url = baseurl + '/api/v1/users/login'; fetch(url, { mode: 'cors', - method: 'POST', - body: JSON.stringify(data), - credentials: 'include', - crossDomain: true, - withCredentials: true, - headers: { - 'Content-Type': 'application/json; charset=utf-8', - }, + method: 'POST', + body: JSON.stringify(data), + credentials: 'include', + crossDomain: true, + withCredentials: true, + headers: { + 'Content-Type': 'application/json; charset=utf-8', + }, }) - .then(response => - response.json().then(responseJson => { - if (responseJson["success"] === false) { - setLoginInfo(responseJson["reason"]) - } else { - setLoginInfo("Successful login, rerouting") - for (var key in responseJson["cookies"]) { - setCookie(responseJson["cookies"][key].key, responseJson["cookies"][key].value, {path: "/"}) - } + .then(response => + response.json().then(responseJson => { + if (responseJson["success"] === false) { + setLoginInfo(responseJson["reason"]) + } else { + setLoginInfo("Successful login, rerouting") + for (var key in responseJson["cookies"]) { + setCookie(responseJson["cookies"][key].key, responseJson["cookies"][key].value, { path: "/" }) + } - setIsLoggedIn(true) - window.location.pathname = "/workflows" - } - }), - ) - .catch(error => { - setLoginInfo("Error in userdata: " + error) - }); + setIsLoggedIn(true) + window.location.pathname = "/workflows" + } + }), + ) + .catch(error => { + setLoginInfo("Error in userdata: " + error) + }); } else { - url = baseurl+'/api/v1/users/register'; + url = baseurl + '/api/v1/users/register'; fetch(url, { method: 'POST', body: JSON.stringify(data), @@ -131,27 +125,27 @@ const LoginDialog = props => { 'Content-Type': 'application/json', }, }) - .then(response => - response.json().then(responseJson => { - if (responseJson["success"] === false) { - setLoginInfo(responseJson["reason"]) - } else { - setLoginInfo("Successful register :)") - } - }), - ) - .catch(error => { - setLoginInfo("Error in userdata: ", error) - }); + .then(response => + response.json().then(responseJson => { + if (responseJson["success"] === false) { + setLoginInfo(responseJson["reason"]) + } else { + setLoginInfo("Successful register :)") + } + }), + ) + .catch(error => { + setLoginInfo("Error in userdata: ", error) + }); } } const onChangeUser = (e) => { - setUsername(e.target.value) + setUsername(e.target.value) } const onChangePass = (e) => { - setPassword(e.target.value) + setPassword(e.target.value) } //const onClickRegister = () => { @@ -167,25 +161,32 @@ const LoginDialog = props => { //var loginChange = register ? (

Want to register? Click here.

) : (

Go back to login? Click here.

); var formtitle = register ?
Login
:
Register
- // {formtitle} - - const basedata = + // {formtitle} + + console.log("THEME: ", theme.palette.surfaceColor) + const basedata =
- -
+ +

{formtitle}

Username
{ id="emailfield" margin="normal" variant="outlined" - onChange={onChangeUser} + onChange={onChangeUser} />
- Password + Password
{ placeholder="**********" margin="normal" variant="outlined" - onChange={onChangePass} + onChange={onChangePass} />
-
- - +
+ +
-
+
{loginInfo}
- const loadedCheck = isLoaded ? + const loadedCheck = isLoaded ?
- {basedata} + {basedata}
:
diff --git a/frontend/src/Oauth2.js b/frontend/src/views/Oauth2.jsx similarity index 100% rename from frontend/src/Oauth2.js rename to frontend/src/views/Oauth2.jsx diff --git a/frontend/src/Post.js b/frontend/src/views/Post.jsx similarity index 100% rename from frontend/src/Post.js rename to frontend/src/views/Post.jsx diff --git a/frontend/src/PrivacyPolicy.js b/frontend/src/views/PrivacyPolicy.jsx similarity index 100% rename from frontend/src/PrivacyPolicy.js rename to frontend/src/views/PrivacyPolicy.jsx diff --git a/frontend/src/RegisterLink.js b/frontend/src/views/RegisterLink.jsx similarity index 100% rename from frontend/src/RegisterLink.js rename to frontend/src/views/RegisterLink.jsx diff --git a/frontend/src/RegisterPage.js b/frontend/src/views/RegisterPage.jsx similarity index 100% rename from frontend/src/RegisterPage.js rename to frontend/src/views/RegisterPage.jsx diff --git a/frontend/src/Schedules.js b/frontend/src/views/Schedules.jsx similarity index 100% rename from frontend/src/Schedules.js rename to frontend/src/views/Schedules.jsx diff --git a/frontend/src/SettingsPage.js b/frontend/src/views/SettingsPage.jsx similarity index 90% rename from frontend/src/SettingsPage.js rename to frontend/src/views/SettingsPage.jsx index 02575957..52f301b2 100644 --- a/frontend/src/SettingsPage.js +++ b/frontend/src/views/SettingsPage.jsx @@ -7,23 +7,11 @@ import {Link} from 'react-router-dom'; import TextField from '@material-ui/core/TextField'; import { useAlert } from "react-alert"; +import { useTheme } from '@material-ui/core/styles'; - -//const tmpdata = { -// "username": "frikky", -// "firstname": "fred", -// "lastname": "ode", -// "title": "topkek", -// "companyname": "company here", -// "email": "your email pls", -// "phone": "PHONE!!", -//} - -// FIXME - add fetch for data fields -// FIXME - remove tmpdata -// FIXME: Use isLoggedIn :) const Settings = (props) => { - const { globalUrl, isLoaded, userdata, surfaceColor, inputColor } = props; + const { globalUrl, isLoaded, userdata, } = props; + const theme = useTheme(); const alert = useAlert() const [username, setUsername] = useState(""); @@ -61,7 +49,7 @@ const Settings = (props) => { paddingRight: "30px", paddingBottom: "30px", paddingTop: "30px", - backgroundColor: surfaceColor, + backgroundColor: theme.palette.surfaceColor, display: "flex", flexDirection: "column" } @@ -190,7 +178,7 @@ const Settings = (props) => {

APIKEY

What is the API key used for? {

Settings

{
{ onChange={e => setFirstname(e.target.value)} /> {
{ onChange={e => setTitle(e.target.value)} /> {
{ onChange={e => setEmail(e.target.value)} /> {

Password

{
{ onChange={e => setNewPassword(e.target.value)} /> { const { globalUrl, isLoaded } = props; diff --git a/frontend/src/Workflows.js b/frontend/src/views/Workflows.jsx similarity index 99% rename from frontend/src/Workflows.js rename to frontend/src/views/Workflows.jsx index 407e6186..1f55de4f 100644 --- a/frontend/src/Workflows.js +++ b/frontend/src/views/Workflows.jsx @@ -563,7 +563,7 @@ const Workflows = (props) => { } return ( - {}}> + {}}>
@@ -988,7 +988,7 @@ const Workflows = (props) => {
Collapse results
+ label={
Collapse results
} control={ {setCollapseJson(!collapseJson)}} />} />
diff --git a/functions/onprem/orborus/orborus.go b/functions/onprem/orborus/orborus.go index d86ba371..fbee4052 100644 --- a/functions/onprem/orborus/orborus.go +++ b/functions/onprem/orborus/orborus.go @@ -78,10 +78,11 @@ func init() { // Skip random containers. Only handle things related to Shuffle. for _, container := range containers { found := false - //log.Printf("Running? %#v", container) - if container.State != "running" { - continue - } + + // Bad states - it might just be created sometimes, leading to now netowkr + //if container.State == "restarting" || container.State == "paused" || container.State == "exited" || container.State == "dead" { + // continue + //} for _, name := range container.Names { if !strings.Contains(strings.ToLower(name), containerIdentifier) { @@ -120,17 +121,10 @@ func deployWorker(image string, identifier string, env []string) { }, } - // ROFL: https://docker-py.readthedocs.io/en/1.4.0/volumes/ - config := &container.Config{ - Image: image, - Env: env, - } - // Look for Shuffle network and set it - - // FIXME: Move this out of here and have it be a global setting. During init? networkConfig := &network.NetworkingConfig{} if len(shuffleNetwork) > 0 { + log.Printf("Starting worker with network %s", shuffleNetwork) networkConfig = &network.NetworkingConfig{ EndpointsConfig: map[string]*network.EndpointSettings{ shuffleNetwork: { @@ -139,7 +133,15 @@ func deployWorker(image string, identifier string, env []string) { }, } - env = append(env, fmt.Sprintf("DOCKER_NETWORK", shuffleNetwork)) + env = append(env, fmt.Sprintf("DOCKER_NETWORK=%s", shuffleNetwork)) + } else { + log.Printf("Starting worker WITHOUT any specified network: %s", shuffleNetwork) + } + + // ROFL: https://docker-py.readthedocs.io/en/1.4.0/volumes/ + config := &container.Config{ + Image: image, + Env: env, } //test := &network.EndpointSettings{ diff --git a/functions/onprem/worker/worker.go b/functions/onprem/worker/worker.go index edb9c39c..48b11ebc 100644 --- a/functions/onprem/worker/worker.go +++ b/functions/onprem/worker/worker.go @@ -1107,6 +1107,13 @@ func main() { } } + shuffleNetwork := os.Getenv("DOCKER_NETWORK") + if len(shuffleNetwork) > 0 { + log.Printf("Running with Docker network %s", shuffleNetwork) + } else { + log.Printf("No docker network specified for Worker.") + } + // WORKER_TESTING_WORKFLOW should be a workflow ID authorization := "" executionId := ""