@@ -3,9 +3,10 @@ ORG_ID=Shuffle
|
||||
ENVIRONMENT_NAME=Shuffle
|
||||
|
||||
# Remote github config for first load
|
||||
SHUFFLE_DOWNLOAD_WORKFLOW_LOCATION=
|
||||
SHUFFLE_DOWNLOAD_AUTH_USERNAME=
|
||||
SHUFFLE_DOWNLOAD_AUTH_PASSWORD=
|
||||
APP_DOWNLOAD_LOCATION=https://github.com/frikky/shuffle-apps
|
||||
APP_DOWNLOAD_AUTH_USERNAME=
|
||||
APP_DOWNLOAD_AUTH_PASSWORD=
|
||||
|
||||
# User config for first load. Username & PW: min length 3
|
||||
SHUFFLE_DEFAULT_USERNAME=
|
||||
|
||||
+41
-10
@@ -254,11 +254,14 @@ func makePythoncode(swagger *openapi3.Swagger, name, url, method string, paramet
|
||||
if len(optionalQueries) > 0 {
|
||||
queryString += ", "
|
||||
for _, query := range optionalQueries {
|
||||
// Check if it's a part of the URL already
|
||||
queryString += fmt.Sprintf("%s=\"\", ", query)
|
||||
queryData += fmt.Sprintf(`
|
||||
if %s:
|
||||
url += f"&%s={%s}"`, query, query, query)
|
||||
}
|
||||
} else {
|
||||
//log.Printf("No optional queries?")
|
||||
}
|
||||
|
||||
// api.Authentication.Parameters[0].Value = "BearerAuth"
|
||||
@@ -398,7 +401,7 @@ func makePythoncode(swagger *openapi3.Swagger, name, url, method string, paramet
|
||||
verifyAddin,
|
||||
)
|
||||
|
||||
//log.Printf("%s", data)
|
||||
//log.Printf(data)
|
||||
return functionname, data
|
||||
}
|
||||
|
||||
@@ -594,10 +597,10 @@ func generateYaml(swagger *openapi3.Swagger, newmd5 string) (*openapi3.Swagger,
|
||||
pythonFunctions := []string{}
|
||||
for actualPath, path := range swagger.Paths {
|
||||
actualPath = strings.Replace(actualPath, " ", "_", -1)
|
||||
actualPath = strings.Replace(actualPath, ".", "", -1)
|
||||
actualPath = strings.Replace(actualPath, ".", "", -1)
|
||||
//actualPath = strings.Replace(actualPath, ".", "", -1)
|
||||
actualPath = strings.Replace(actualPath, "\\", "", -1)
|
||||
|
||||
// FIXME: Handle everything behind questionmark (?) with dots as well.
|
||||
// https://godoc.org/github.com/getkin/kin-openapi/openapi3#PathItem
|
||||
if path.Get != nil {
|
||||
action, curCode := handleGet(swagger, api, extraParameters, path, actualPath)
|
||||
@@ -936,7 +939,11 @@ func handleConnect(swagger *openapi3.Swagger, api WorkflowApp, extraParameters [
|
||||
continue
|
||||
}
|
||||
|
||||
if firstQuery {
|
||||
if strings.Contains(baseUrl, fmt.Sprintf("{%s}", param.Value.Name)) {
|
||||
continue
|
||||
}
|
||||
|
||||
if firstQuery && !strings.Contains(baseUrl, "?") {
|
||||
baseUrl = fmt.Sprintf("%s?%s={%s}", baseUrl, param.Value.Name, param.Value.Name)
|
||||
} else {
|
||||
baseUrl = fmt.Sprintf("%s&%s={%s}", baseUrl, param.Value.Name, param.Value.Name)
|
||||
@@ -1081,7 +1088,11 @@ func handleGet(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wor
|
||||
continue
|
||||
}
|
||||
|
||||
if firstQuery {
|
||||
if strings.Contains(baseUrl, fmt.Sprintf("{%s}", param.Value.Name)) {
|
||||
continue
|
||||
}
|
||||
|
||||
if firstQuery && !strings.Contains(baseUrl, "?") {
|
||||
baseUrl = fmt.Sprintf("%s?%s={%s}", baseUrl, param.Value.Name, param.Value.Name)
|
||||
} else {
|
||||
baseUrl = fmt.Sprintf("%s&%s={%s}", baseUrl, param.Value.Name, param.Value.Name)
|
||||
@@ -1224,7 +1235,11 @@ func handleHead(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wo
|
||||
continue
|
||||
}
|
||||
|
||||
if firstQuery {
|
||||
if strings.Contains(baseUrl, fmt.Sprintf("{%s}", param.Value.Name)) {
|
||||
continue
|
||||
}
|
||||
|
||||
if firstQuery && !strings.Contains(baseUrl, "?") {
|
||||
baseUrl = fmt.Sprintf("%s?%s={%s}", baseUrl, param.Value.Name, param.Value.Name)
|
||||
} else {
|
||||
baseUrl = fmt.Sprintf("%s&%s={%s}", baseUrl, param.Value.Name, param.Value.Name)
|
||||
@@ -1368,7 +1383,11 @@ func handleDelete(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []
|
||||
continue
|
||||
}
|
||||
|
||||
if firstQuery {
|
||||
if strings.Contains(baseUrl, fmt.Sprintf("{%s}", param.Value.Name)) {
|
||||
continue
|
||||
}
|
||||
|
||||
if firstQuery && !strings.Contains(baseUrl, "?") {
|
||||
baseUrl = fmt.Sprintf("%s?%s={%s}", baseUrl, param.Value.Name, param.Value.Name)
|
||||
} else {
|
||||
baseUrl = fmt.Sprintf("%s&%s={%s}", baseUrl, param.Value.Name, param.Value.Name)
|
||||
@@ -1511,7 +1530,11 @@ func handlePost(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wo
|
||||
continue
|
||||
}
|
||||
|
||||
if firstQuery {
|
||||
if strings.Contains(baseUrl, fmt.Sprintf("{%s}", param.Value.Name)) {
|
||||
continue
|
||||
}
|
||||
|
||||
if firstQuery && !strings.Contains(baseUrl, "?") {
|
||||
baseUrl = fmt.Sprintf("%s?%s={%s}", baseUrl, param.Value.Name, param.Value.Name)
|
||||
} else {
|
||||
baseUrl = fmt.Sprintf("%s&%s={%s}", baseUrl, param.Value.Name, param.Value.Name)
|
||||
@@ -1654,7 +1677,11 @@ func handlePatch(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []W
|
||||
continue
|
||||
}
|
||||
|
||||
if firstQuery {
|
||||
if strings.Contains(baseUrl, fmt.Sprintf("{%s}", param.Value.Name)) {
|
||||
continue
|
||||
}
|
||||
|
||||
if firstQuery && !strings.Contains(baseUrl, "?") {
|
||||
baseUrl = fmt.Sprintf("%s?%s={%s}", baseUrl, param.Value.Name, param.Value.Name)
|
||||
} else {
|
||||
baseUrl = fmt.Sprintf("%s&%s={%s}", baseUrl, param.Value.Name, param.Value.Name)
|
||||
@@ -1797,7 +1824,11 @@ func handlePut(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wor
|
||||
continue
|
||||
}
|
||||
|
||||
if firstQuery {
|
||||
if strings.Contains(baseUrl, fmt.Sprintf("{%s}", param.Value.Name)) {
|
||||
continue
|
||||
}
|
||||
|
||||
if firstQuery && !strings.Contains(baseUrl, "?") {
|
||||
baseUrl = fmt.Sprintf("%s?%s={%s}", baseUrl, param.Value.Name, param.Value.Name)
|
||||
} else {
|
||||
baseUrl = fmt.Sprintf("%s&%s={%s}", baseUrl, param.Value.Name, param.Value.Name)
|
||||
|
||||
+53
-12
@@ -158,6 +158,9 @@ type Environment struct {
|
||||
Name string `datastore:"name"`
|
||||
Type string `datastore:"type"`
|
||||
Registered bool `datastore:"registered"`
|
||||
Default bool `datastore:"default" json:"default"`
|
||||
Archived bool `datastore:"archived" json:"archived"`
|
||||
Id string `datastore:"id" json:"id"`
|
||||
}
|
||||
|
||||
type User struct {
|
||||
@@ -1053,16 +1056,29 @@ func handleSetEnvironments(resp http.ResponseWriter, request *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Clear old data
|
||||
for _, item := range environments {
|
||||
err = DeleteKey(ctx, "Environments", item.Name)
|
||||
if err != nil {
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false, "reason": "Error cleaning up environment"}`))
|
||||
return
|
||||
// Clear old data? Removed for archiving purpose. No straight deletion
|
||||
//for _, item := range environments {
|
||||
// err = DeleteKey(ctx, "Environments", item.Name)
|
||||
// if err != nil {
|
||||
// resp.WriteHeader(401)
|
||||
// resp.Write([]byte(`{"success": false, "reason": "Error cleaning up environment"}`))
|
||||
// return
|
||||
// }
|
||||
//}
|
||||
|
||||
openEnvironments := 0
|
||||
for _, item := range newEnvironments {
|
||||
if !item.Archived {
|
||||
openEnvironments += 1
|
||||
}
|
||||
}
|
||||
|
||||
if openEnvironments < 1 {
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false, "reason": "Can't archived all environments"}`))
|
||||
return
|
||||
}
|
||||
|
||||
for _, item := range newEnvironments {
|
||||
err = setEnvironment(ctx, &item)
|
||||
if err != nil {
|
||||
@@ -1072,9 +1088,10 @@ func handleSetEnvironments(resp http.ResponseWriter, request *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
//DeleteKey(ctx, entity string, value string) error {
|
||||
// FIXME - check which are in use
|
||||
log.Printf("FIXME: Set new environments: %#v", newEnvironments)
|
||||
log.Printf("DONT DELETE ONES THAT ARE IN USE")
|
||||
//log.Printf("FIXME: Set new environments: %#v", newEnvironments)
|
||||
//log.Printf("DONT DELETE ONES THAT ARE IN USE")
|
||||
|
||||
resp.WriteHeader(200)
|
||||
resp.Write([]byte(`{"success": true}`))
|
||||
@@ -5995,7 +6012,7 @@ func verifySwagger(resp http.ResponseWriter, request *http.Request) {
|
||||
if err != nil {
|
||||
log.Printf("Docker build error: %s", err)
|
||||
resp.WriteHeader(500)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "Error in Docker build"}`)))
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Error in Docker build"}`)))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -6327,8 +6344,8 @@ func runInit(ctx context.Context) {
|
||||
url = "https://github.com/frikky/shuffle-apps"
|
||||
}
|
||||
|
||||
username := os.Getenv("APP_DOWNLOAD_AUTH_USERNAME")
|
||||
password := os.Getenv("APP_DOWNLOAD_AUTH_PASSWORD")
|
||||
username := os.Getenv("SHUFFLE_DOWNLOAD_AUTH_USERNAME")
|
||||
password := os.Getenv("SHUFFLE_DOWNLOAD_AUTH_PASSWORD")
|
||||
cloneOptions := &git.CloneOptions{
|
||||
URL: url,
|
||||
}
|
||||
@@ -6388,6 +6405,30 @@ func runInit(ctx context.Context) {
|
||||
log.Printf("Finished downloading extra API samples")
|
||||
}
|
||||
|
||||
workflowLocation := os.Getenv("SHUFFLE_DOWNLOAD_WORKFLOW_LOCATION")
|
||||
if len(workflowLocation) > 0 {
|
||||
log.Printf("Downloading WORKFLOWS from %s if no workflows - EXTRA workflows", workflowLocation)
|
||||
q := datastore.NewQuery("workflow")
|
||||
var workflows []Workflow
|
||||
_, err = dbclient.GetAll(ctx, q, &workflows)
|
||||
if err != nil {
|
||||
log.Printf("Error getting workflows: %s", err)
|
||||
} else {
|
||||
if len(workflows) == 0 {
|
||||
username := os.Getenv("SHUFFLE_DOWNLOAD_AUTH_USERNAME")
|
||||
password := os.Getenv("SHUFFLE_DOWNLOAD_AUTH_PASSWORD")
|
||||
err = loadGithubWorkflows(workflowLocation, username, password, "")
|
||||
if err != nil {
|
||||
log.Printf("Failed to upload workflows from github: %s", err)
|
||||
} else {
|
||||
log.Printf("Finished downloading workflows from github!")
|
||||
}
|
||||
} else {
|
||||
log.Printf("Skipping because there are %d workflows already", len(workflows))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
log.Printf("Finished INIT")
|
||||
}
|
||||
|
||||
|
||||
+95
-63
@@ -120,6 +120,8 @@ type WorkflowApp struct {
|
||||
} `json:"contact_info" datastore:"contact_info" yaml:"contact_info" required:false`
|
||||
Actions []WorkflowAppAction `json:"actions" yaml:"actions" required:true datastore:"actions,noindex"`
|
||||
Authentication Authentication `json:"authentication" yaml:"authentication" required:false datastore:"authentication"`
|
||||
Tags []string `json:"tags" yaml:"tags" required:false datastore:"activated"`
|
||||
Category []string `json:"category" yaml:"category" required:false datastore:"category"`
|
||||
}
|
||||
|
||||
type WorkflowAppActionParameter struct {
|
||||
@@ -129,6 +131,7 @@ type WorkflowAppActionParameter struct {
|
||||
Example string `json:"example" datastore:"example" yaml:"example"`
|
||||
Value string `json:"value" datastore:"value" yaml:"value,omitempty"`
|
||||
Multiline bool `json:"multiline" datastore:"multiline" yaml:"multiline"`
|
||||
Options []string `json:"options" datastore:"options" yaml:"options"`
|
||||
ActionField string `json:"action_field" datastore:"action_field" yaml:"actionfield,omitempty"`
|
||||
Variant string `json:"variant" datastore:"variant" yaml:"variant,omitempty"`
|
||||
Required bool `json:"required" datastore:"required" yaml:"required"`
|
||||
@@ -192,7 +195,7 @@ type WorkflowExecution struct {
|
||||
Description string `json:"description" datastore:"description"`
|
||||
ID string `json:"id" datastore:"id"`
|
||||
Name string `json:"name" datastore:"name"`
|
||||
Value string `json:"value" datastore:"value"`
|
||||
Value string `json:"value" datastore:"value,noindex"`
|
||||
} `json:"execution_variables,omitempty" datastore:"execution_variables,omitempty"`
|
||||
}
|
||||
|
||||
@@ -217,7 +220,7 @@ type Action struct {
|
||||
Description string `json:"description" datastore:"description"`
|
||||
ID string `json:"id" datastore:"id"`
|
||||
Name string `json:"name" datastore:"name"`
|
||||
Value string `json:"value" datastore:"value"`
|
||||
Value string `json:"value" datastore:"value,noindex"`
|
||||
} `json:"execution_variable,omitempty" datastore:"execution_variable,omitempty"`
|
||||
Position struct {
|
||||
X float64 `json:"x" datastore:"x"`
|
||||
@@ -307,7 +310,7 @@ type Workflow struct {
|
||||
Description string `json:"description" datastore:"description"`
|
||||
ID string `json:"id" datastore:"id"`
|
||||
Name string `json:"name" datastore:"name"`
|
||||
Value string `json:"value" datastore:"value"`
|
||||
Value string `json:"value" datastore:"value,noindex"`
|
||||
} `json:"execution_variables,omitempty" datastore:"execution_variables"`
|
||||
}
|
||||
|
||||
@@ -1121,6 +1124,10 @@ func getWorkflows(resp http.ResponseWriter, request *http.Request) {
|
||||
|
||||
// With user, do a search for workflows with user or user's org attached
|
||||
q := datastore.NewQuery("workflow").Filter("owner =", user.Id)
|
||||
if user.Role == "admin" {
|
||||
q = datastore.NewQuery("workflow")
|
||||
}
|
||||
|
||||
var workflows []Workflow
|
||||
_, err = dbclient.GetAll(ctx, q, &workflows)
|
||||
if err != nil {
|
||||
@@ -1236,11 +1243,16 @@ func setNewWorkflow(resp http.ResponseWriter, request *http.Request) {
|
||||
workflowapps, err := getAllWorkflowApps(ctx)
|
||||
if err == nil {
|
||||
// FIXME: Add real env
|
||||
//q := datastore.NewQuery("Environments").Limit(1)
|
||||
//count, err := dbclient.Get(ctx, q)
|
||||
//envName := "Shuffle"
|
||||
//if err == nil {
|
||||
//}
|
||||
envName := "Shuffle"
|
||||
environments, err := getEnvironments(ctx)
|
||||
if err == nil {
|
||||
for _, env := range environments {
|
||||
if env.Default {
|
||||
envName = env.Name
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, item := range workflowapps {
|
||||
if item.Name == "Testing" && item.AppVersion == "1.0.0" {
|
||||
@@ -1249,7 +1261,7 @@ func setNewWorkflow(resp http.ResponseWriter, request *http.Request) {
|
||||
newActions = append(newActions, Action{
|
||||
Label: "Start node",
|
||||
Name: "hello_world",
|
||||
Environment: "Shuffle",
|
||||
Environment: envName,
|
||||
Parameters: []WorkflowAppActionParameter{},
|
||||
Position: struct {
|
||||
X float64 "json:\"x\" datastore:\"x\""
|
||||
@@ -3100,6 +3112,18 @@ func getWorkflow(ctx context.Context, id string) (*Workflow, error) {
|
||||
return workflow, nil
|
||||
}
|
||||
|
||||
func getEnvironments(ctx context.Context) ([]Environment, error) {
|
||||
var environments []Environment
|
||||
q := datastore.NewQuery("Environments")
|
||||
|
||||
_, err := dbclient.GetAll(ctx, q, &environments)
|
||||
if err != nil {
|
||||
return []Environment{}, err
|
||||
}
|
||||
|
||||
return environments, nil
|
||||
}
|
||||
|
||||
func getAllWorkflows(ctx context.Context) ([]Workflow, error) {
|
||||
var allworkflows []Workflow
|
||||
q := datastore.NewQuery("workflow")
|
||||
@@ -4045,6 +4069,62 @@ func deployWebhookFunction(ctx context.Context, name, localization, applocation
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadGithubWorkflows(url, username, password, userId string) error {
|
||||
fs := memfs.New()
|
||||
|
||||
if strings.Contains(url, "github") || strings.Contains(url, "gitlab") || strings.Contains(url, "bitbucket") {
|
||||
cloneOptions := &git.CloneOptions{
|
||||
URL: url,
|
||||
}
|
||||
|
||||
// FIXME: Better auth.
|
||||
if len(username) > 0 && len(password) > 0 {
|
||||
cloneOptions.Auth = &http2.BasicAuth{
|
||||
|
||||
Username: username,
|
||||
Password: password,
|
||||
}
|
||||
}
|
||||
|
||||
storer := memory.NewStorage()
|
||||
r, err := git.Clone(storer, fs, cloneOptions)
|
||||
if err != nil {
|
||||
log.Printf("Failed loading repo into memory: %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
dir, err := fs.ReadDir("/")
|
||||
if err != nil {
|
||||
log.Printf("FAiled reading folder: %s", err)
|
||||
}
|
||||
_ = r
|
||||
|
||||
log.Printf("Starting workflow folder iteration")
|
||||
iterateWorkflowGithubFolders(fs, dir, "", "", userId)
|
||||
|
||||
} else if strings.Contains(url, "s3") {
|
||||
//https://docs.aws.amazon.com/sdk-for-go/api/service/s3/
|
||||
|
||||
//sess := session.Must(session.NewSession())
|
||||
//downloader := s3manager.NewDownloader(sess)
|
||||
|
||||
//// Write the contents of S3 Object to the file
|
||||
//storer := memory.NewStorage()
|
||||
//n, err := downloader.Download(storer, &s3.GetObjectInput{
|
||||
// Bucket: aws.String(myBucket),
|
||||
// Key: aws.String(myString),
|
||||
//})
|
||||
//if err != nil {
|
||||
// return fmt.Errorf("failed to download file, %v", err)
|
||||
//}
|
||||
//fmt.Printf("file downloaded, %d bytes\n", n)
|
||||
} else {
|
||||
return errors.New(fmt.Sprintf("URL %s is unsupported when downloading workflows", url))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadSpecificWorkflows(resp http.ResponseWriter, request *http.Request) {
|
||||
cors := handleCors(resp, request)
|
||||
if cors {
|
||||
@@ -4064,7 +4144,7 @@ func loadSpecificWorkflows(resp http.ResponseWriter, request *http.Request) {
|
||||
if user.Role != "admin" {
|
||||
log.Printf("Wrong user (%s) when downloading from github", user.Username)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
resp.Write([]byte(`{"success": false, "reason": "Downloading remotely requires admin"}`))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -4093,59 +4173,11 @@ func loadSpecificWorkflows(resp http.ResponseWriter, request *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
fs := memfs.New()
|
||||
|
||||
if strings.Contains(tmpBody.URL, "github") || strings.Contains(tmpBody.URL, "gitlab") || strings.Contains(tmpBody.URL, "bitbucket") {
|
||||
cloneOptions := &git.CloneOptions{
|
||||
URL: tmpBody.URL,
|
||||
}
|
||||
|
||||
// FIXME: Better auth.
|
||||
if len(tmpBody.Field1) > 0 && len(tmpBody.Field2) > 0 {
|
||||
cloneOptions.Auth = &http2.BasicAuth{
|
||||
|
||||
Username: tmpBody.Field1,
|
||||
Password: tmpBody.Field2,
|
||||
}
|
||||
}
|
||||
|
||||
storer := memory.NewStorage()
|
||||
r, err := git.Clone(storer, fs, cloneOptions)
|
||||
if err != nil {
|
||||
log.Printf("Failed loading repo into memory: %s", err)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, err)))
|
||||
return
|
||||
}
|
||||
|
||||
dir, err := fs.ReadDir("/")
|
||||
if err != nil {
|
||||
log.Printf("FAiled reading folder: %s", err)
|
||||
}
|
||||
_ = r
|
||||
|
||||
log.Printf("Starting workflow folder iteration")
|
||||
iterateWorkflowGithubFolders(fs, dir, "", "", user.Id)
|
||||
|
||||
} else if strings.Contains(tmpBody.URL, "s3") {
|
||||
//https://docs.aws.amazon.com/sdk-for-go/api/service/s3/
|
||||
|
||||
//sess := session.Must(session.NewSession())
|
||||
//downloader := s3manager.NewDownloader(sess)
|
||||
|
||||
//// Write the contents of S3 Object to the file
|
||||
//storer := memory.NewStorage()
|
||||
//n, err := downloader.Download(storer, &s3.GetObjectInput{
|
||||
// Bucket: aws.String(myBucket),
|
||||
// Key: aws.String(myString),
|
||||
//})
|
||||
//if err != nil {
|
||||
// return fmt.Errorf("failed to download file, %v", err)
|
||||
//}
|
||||
//fmt.Printf("file downloaded, %d bytes\n", n)
|
||||
} else {
|
||||
err = loadGithubWorkflows(tmpBody.URL, tmpBody.Field1, tmpBody.Field2, user.Id)
|
||||
if err != nil {
|
||||
log.Printf("Failed to update workflows: %s", err)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s is unsupported. Try e.g. github"}`, tmpBody.URL)))
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -4489,7 +4521,7 @@ func iterateWorkflowGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra
|
||||
log.Printf("Failed setting (download) workflow: %s", err)
|
||||
continue
|
||||
}
|
||||
log.Printf("Uploaded workflow %s!", filename)
|
||||
log.Printf("Uploaded workflow %s for user %s!", filename, userId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ services:
|
||||
depends_on:
|
||||
- backend
|
||||
backend:
|
||||
build: ./backend
|
||||
#build: ./backend
|
||||
image: frikky/shuffle:backend
|
||||
container_name: shuffle-backend
|
||||
hostname: ${BACKEND_HOSTNAME}
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
FROM node as builder
|
||||
|
||||
RUN mkdir /usr/src/app
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
ENV PATH /usr/src/app/node_modules/.bin:$PATH
|
||||
|
||||
COPY package.json /usr/src/app/package.json
|
||||
|
||||
RUN npm install --verbose
|
||||
@@ -15,6 +17,10 @@ COPY ./src /usr/src/app/src/
|
||||
COPY ./*.sh /usr/src/app/
|
||||
COPY ./*.json /usr/src/app/
|
||||
|
||||
# There were issues with the webpack installer from package.json
|
||||
RUN rm -rf /usr/src/app/node_modules/webpack
|
||||
RUN npm install webpack@4.42.0
|
||||
|
||||
RUN npm run-script build
|
||||
|
||||
# Production environment
|
||||
|
||||
Generated
+396
-43
@@ -4332,13 +4332,14 @@
|
||||
}
|
||||
},
|
||||
"asn1.js": {
|
||||
"version": "4.10.1",
|
||||
"resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
|
||||
"integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
|
||||
"version": "5.4.1",
|
||||
"resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz",
|
||||
"integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==",
|
||||
"requires": {
|
||||
"bn.js": "^4.0.0",
|
||||
"inherits": "^2.0.1",
|
||||
"minimalistic-assert": "^1.0.0"
|
||||
"minimalistic-assert": "^1.0.0",
|
||||
"safer-buffer": "^2.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"bn.js": {
|
||||
@@ -5265,9 +5266,9 @@
|
||||
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
|
||||
},
|
||||
"bn.js": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.2.tgz",
|
||||
"integrity": "sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA=="
|
||||
"version": "5.1.3",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz",
|
||||
"integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ=="
|
||||
},
|
||||
"body-parser": {
|
||||
"version": "1.19.0",
|
||||
@@ -5438,15 +5439,15 @@
|
||||
}
|
||||
},
|
||||
"browserify-sign": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.0.tgz",
|
||||
"integrity": "sha512-hEZC1KEeYuoHRqhGhTy6gWrpJA3ZDjFWv0DE61643ZnOXAKJb3u7yWcrU0mMc9SwAqK1n7myPGndkp0dFG7NFA==",
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz",
|
||||
"integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==",
|
||||
"requires": {
|
||||
"bn.js": "^5.1.1",
|
||||
"browserify-rsa": "^4.0.1",
|
||||
"create-hash": "^1.2.0",
|
||||
"create-hmac": "^1.1.7",
|
||||
"elliptic": "^6.5.2",
|
||||
"elliptic": "^6.5.3",
|
||||
"inherits": "^2.0.4",
|
||||
"parse-asn1": "^5.1.5",
|
||||
"readable-stream": "^3.6.0",
|
||||
@@ -5868,9 +5869,9 @@
|
||||
}
|
||||
},
|
||||
"class-transformer": {
|
||||
"version": "0.2.3",
|
||||
"resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.2.3.tgz",
|
||||
"integrity": "sha512-qsP+0xoavpOlJHuYsQJsN58HXSl8Jvveo+T37rEvCEeRfMWoytAyR0Ua/YsFgpM6AZYZ/og2PJwArwzJl1aXtQ=="
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.3.1.tgz",
|
||||
"integrity": "sha512-cKFwohpJbuMovS8xVLmn8N2AUbAuc8pVo4zEfsUVo8qgECOogns1WVk/FkOZoxhOPTyTYFckuoH+13FO+MQ8GA=="
|
||||
},
|
||||
"class-utils": {
|
||||
"version": "0.3.6",
|
||||
@@ -6341,12 +6342,12 @@
|
||||
}
|
||||
},
|
||||
"create-ecdh": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz",
|
||||
"integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==",
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz",
|
||||
"integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==",
|
||||
"requires": {
|
||||
"bn.js": "^4.1.0",
|
||||
"elliptic": "^6.0.0"
|
||||
"elliptic": "^6.5.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"bn.js": {
|
||||
@@ -7558,9 +7559,9 @@
|
||||
"integrity": "sha512-vcTeLpPm4+ccoYFXnepvkFt0KujdyrBU19KNEO40Pnkhta6mUi2K0Dn7NmpRcNz7BvysnSqeuIYScP003HWuYg=="
|
||||
},
|
||||
"elliptic": {
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz",
|
||||
"integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==",
|
||||
"version": "6.5.3",
|
||||
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz",
|
||||
"integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==",
|
||||
"requires": {
|
||||
"bn.js": "^4.4.0",
|
||||
"brorand": "^1.0.1",
|
||||
@@ -7610,9 +7611,9 @@
|
||||
}
|
||||
},
|
||||
"enhanced-resolve": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.2.0.tgz",
|
||||
"integrity": "sha512-S7eiFb/erugyd1rLb6mQ3Vuq+EXHv5cpCkNqqIkYkBgN2QdFnyCZzFBleqwGEx4lgNGYij81BWnCrFNK7vxvjQ==",
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz",
|
||||
"integrity": "sha512-3e87LvavsdxyoCfGusJnrZ5G8SLPOFeHSNpZI/ATL9a5leXo2k0w6MKnbqhdBad9qTobSfB20Ld7UmgoNbAZkQ==",
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.2",
|
||||
"memory-fs": "^0.5.0",
|
||||
@@ -8250,9 +8251,9 @@
|
||||
"integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ=="
|
||||
},
|
||||
"events": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz",
|
||||
"integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg=="
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz",
|
||||
"integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg=="
|
||||
},
|
||||
"eventsource": {
|
||||
"version": "1.0.7",
|
||||
@@ -13442,13 +13443,12 @@
|
||||
}
|
||||
},
|
||||
"parse-asn1": {
|
||||
"version": "5.1.5",
|
||||
"resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz",
|
||||
"integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==",
|
||||
"version": "5.1.6",
|
||||
"resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz",
|
||||
"integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==",
|
||||
"requires": {
|
||||
"asn1.js": "^4.0.0",
|
||||
"asn1.js": "^5.2.0",
|
||||
"browserify-aes": "^1.0.0",
|
||||
"create-hash": "^1.1.0",
|
||||
"evp_bytestokey": "^1.0.0",
|
||||
"pbkdf2": "^3.0.3",
|
||||
"safe-buffer": "^5.1.1"
|
||||
@@ -15566,11 +15566,205 @@
|
||||
"workbox-webpack-plugin": "4.3.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@webassemblyjs/ast": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz",
|
||||
"integrity": "sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==",
|
||||
"requires": {
|
||||
"@webassemblyjs/helper-module-context": "1.8.5",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.8.5",
|
||||
"@webassemblyjs/wast-parser": "1.8.5"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/floating-point-hex-parser": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz",
|
||||
"integrity": "sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ=="
|
||||
},
|
||||
"@webassemblyjs/helper-api-error": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz",
|
||||
"integrity": "sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA=="
|
||||
},
|
||||
"@webassemblyjs/helper-buffer": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz",
|
||||
"integrity": "sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q=="
|
||||
},
|
||||
"@webassemblyjs/helper-code-frame": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz",
|
||||
"integrity": "sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==",
|
||||
"requires": {
|
||||
"@webassemblyjs/wast-printer": "1.8.5"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/helper-fsm": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz",
|
||||
"integrity": "sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow=="
|
||||
},
|
||||
"@webassemblyjs/helper-module-context": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz",
|
||||
"integrity": "sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==",
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"mamacro": "^0.0.3"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/helper-wasm-bytecode": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz",
|
||||
"integrity": "sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ=="
|
||||
},
|
||||
"@webassemblyjs/helper-wasm-section": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz",
|
||||
"integrity": "sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==",
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/helper-buffer": "1.8.5",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.8.5",
|
||||
"@webassemblyjs/wasm-gen": "1.8.5"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/ieee754": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz",
|
||||
"integrity": "sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==",
|
||||
"requires": {
|
||||
"@xtuc/ieee754": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/leb128": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.8.5.tgz",
|
||||
"integrity": "sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==",
|
||||
"requires": {
|
||||
"@xtuc/long": "4.2.2"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/utf8": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.8.5.tgz",
|
||||
"integrity": "sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw=="
|
||||
},
|
||||
"@webassemblyjs/wasm-edit": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz",
|
||||
"integrity": "sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==",
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/helper-buffer": "1.8.5",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.8.5",
|
||||
"@webassemblyjs/helper-wasm-section": "1.8.5",
|
||||
"@webassemblyjs/wasm-gen": "1.8.5",
|
||||
"@webassemblyjs/wasm-opt": "1.8.5",
|
||||
"@webassemblyjs/wasm-parser": "1.8.5",
|
||||
"@webassemblyjs/wast-printer": "1.8.5"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/wasm-gen": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz",
|
||||
"integrity": "sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==",
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.8.5",
|
||||
"@webassemblyjs/ieee754": "1.8.5",
|
||||
"@webassemblyjs/leb128": "1.8.5",
|
||||
"@webassemblyjs/utf8": "1.8.5"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/wasm-opt": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz",
|
||||
"integrity": "sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==",
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/helper-buffer": "1.8.5",
|
||||
"@webassemblyjs/wasm-gen": "1.8.5",
|
||||
"@webassemblyjs/wasm-parser": "1.8.5"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/wasm-parser": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz",
|
||||
"integrity": "sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==",
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/helper-api-error": "1.8.5",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.8.5",
|
||||
"@webassemblyjs/ieee754": "1.8.5",
|
||||
"@webassemblyjs/leb128": "1.8.5",
|
||||
"@webassemblyjs/utf8": "1.8.5"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/wast-parser": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz",
|
||||
"integrity": "sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==",
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/floating-point-hex-parser": "1.8.5",
|
||||
"@webassemblyjs/helper-api-error": "1.8.5",
|
||||
"@webassemblyjs/helper-code-frame": "1.8.5",
|
||||
"@webassemblyjs/helper-fsm": "1.8.5",
|
||||
"@xtuc/long": "4.2.2"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/wast-printer": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz",
|
||||
"integrity": "sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==",
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/wast-parser": "1.8.5",
|
||||
"@xtuc/long": "4.2.2"
|
||||
}
|
||||
},
|
||||
"acorn": {
|
||||
"version": "6.4.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz",
|
||||
"integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA=="
|
||||
},
|
||||
"cacache": {
|
||||
"version": "12.0.4",
|
||||
"resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz",
|
||||
"integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==",
|
||||
"requires": {
|
||||
"bluebird": "^3.5.5",
|
||||
"chownr": "^1.1.1",
|
||||
"figgy-pudding": "^3.5.1",
|
||||
"glob": "^7.1.4",
|
||||
"graceful-fs": "^4.1.15",
|
||||
"infer-owner": "^1.0.3",
|
||||
"lru-cache": "^5.1.1",
|
||||
"mississippi": "^3.0.0",
|
||||
"mkdirp": "^0.5.1",
|
||||
"move-concurrently": "^1.0.1",
|
||||
"promise-inflight": "^1.0.1",
|
||||
"rimraf": "^2.6.3",
|
||||
"ssri": "^6.0.1",
|
||||
"unique-filename": "^1.1.1",
|
||||
"y18n": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"dotenv": {
|
||||
"version": "8.2.0",
|
||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz",
|
||||
"integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw=="
|
||||
},
|
||||
"eslint-scope": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
|
||||
"integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
|
||||
"requires": {
|
||||
"esrecurse": "^4.1.0",
|
||||
"estraverse": "^4.1.1"
|
||||
}
|
||||
},
|
||||
"fs-extra": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
|
||||
@@ -15586,10 +15780,102 @@
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
|
||||
"integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw=="
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
|
||||
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
|
||||
"requires": {
|
||||
"yallist": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"schema-utils": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
|
||||
"integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
|
||||
"requires": {
|
||||
"ajv": "^6.1.0",
|
||||
"ajv-errors": "^1.0.0",
|
||||
"ajv-keywords": "^3.1.0"
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
|
||||
},
|
||||
"serialize-javascript": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
|
||||
"integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==",
|
||||
"requires": {
|
||||
"randombytes": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
|
||||
},
|
||||
"ssri": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz",
|
||||
"integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==",
|
||||
"requires": {
|
||||
"figgy-pudding": "^3.5.1"
|
||||
}
|
||||
},
|
||||
"webpack": {
|
||||
"version": "4.42.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.42.0.tgz",
|
||||
"integrity": "sha512-EzJRHvwQyBiYrYqhyjW9AqM90dE4+s1/XtCfn7uWg6cS72zH+2VPFAlsnW0+W0cDi0XRjNKUMoJtpSi50+Ph6w==",
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/helper-module-context": "1.8.5",
|
||||
"@webassemblyjs/wasm-edit": "1.8.5",
|
||||
"@webassemblyjs/wasm-parser": "1.8.5",
|
||||
"acorn": "^6.2.1",
|
||||
"ajv": "^6.10.2",
|
||||
"ajv-keywords": "^3.4.1",
|
||||
"chrome-trace-event": "^1.0.2",
|
||||
"enhanced-resolve": "^4.1.0",
|
||||
"eslint-scope": "^4.0.3",
|
||||
"json-parse-better-errors": "^1.0.2",
|
||||
"loader-runner": "^2.4.0",
|
||||
"loader-utils": "^1.2.3",
|
||||
"memory-fs": "^0.4.1",
|
||||
"micromatch": "^3.1.10",
|
||||
"mkdirp": "^0.5.1",
|
||||
"neo-async": "^2.6.1",
|
||||
"node-libs-browser": "^2.2.1",
|
||||
"schema-utils": "^1.0.0",
|
||||
"tapable": "^1.1.3",
|
||||
"terser-webpack-plugin": "^1.4.3",
|
||||
"watchpack": "^1.6.0",
|
||||
"webpack-sources": "^1.4.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"terser-webpack-plugin": {
|
||||
"version": "1.4.5",
|
||||
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz",
|
||||
"integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==",
|
||||
"requires": {
|
||||
"cacache": "^12.0.2",
|
||||
"find-cache-dir": "^2.1.0",
|
||||
"is-wsl": "^1.1.0",
|
||||
"schema-utils": "^1.0.0",
|
||||
"serialize-javascript": "^4.0.0",
|
||||
"source-map": "^0.6.1",
|
||||
"terser": "^4.1.2",
|
||||
"webpack-sources": "^1.4.0",
|
||||
"worker-farm": "^1.7.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
||||
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -18337,14 +18623,81 @@
|
||||
}
|
||||
},
|
||||
"watchpack": {
|
||||
"version": "1.7.2",
|
||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.2.tgz",
|
||||
"integrity": "sha512-ymVbbQP40MFTp+cNMvpyBpBtygHnPzPkHqoIwRRj/0B8KhqQwV8LaKjtbaxF2lK4vl8zN9wCxS46IFCU5K4W0g==",
|
||||
"version": "1.7.4",
|
||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.4.tgz",
|
||||
"integrity": "sha512-aWAgTW4MoSJzZPAicljkO1hsi1oKj/RRq/OJQh2PKI2UKL04c2Bs+MBOB+BBABHTXJpf9mCwHN7ANCvYsvY2sg==",
|
||||
"requires": {
|
||||
"chokidar": "^3.4.0",
|
||||
"chokidar": "^3.4.1",
|
||||
"graceful-fs": "^4.1.2",
|
||||
"neo-async": "^2.5.0",
|
||||
"watchpack-chokidar2": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"anymatch": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
|
||||
"integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"normalize-path": "^3.0.0",
|
||||
"picomatch": "^2.0.4"
|
||||
}
|
||||
},
|
||||
"braces": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"fill-range": "^7.0.1"
|
||||
}
|
||||
},
|
||||
"chokidar": {
|
||||
"version": "3.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz",
|
||||
"integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"anymatch": "~3.1.1",
|
||||
"braces": "~3.0.2",
|
||||
"fsevents": "~2.1.2",
|
||||
"glob-parent": "~5.1.0",
|
||||
"is-binary-path": "~2.1.0",
|
||||
"is-glob": "~4.0.1",
|
||||
"normalize-path": "~3.0.0",
|
||||
"readdirp": "~3.4.0"
|
||||
}
|
||||
},
|
||||
"fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"is-number": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||
"optional": true
|
||||
},
|
||||
"normalize-path": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
||||
"optional": true
|
||||
},
|
||||
"to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"is-number": "^7.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"watchpack-chokidar2": {
|
||||
@@ -18574,9 +18927,9 @@
|
||||
}
|
||||
},
|
||||
"serialize-javascript": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz",
|
||||
"integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==",
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
|
||||
"integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==",
|
||||
"requires": {
|
||||
"randombytes": "^2.1.0"
|
||||
}
|
||||
@@ -18595,15 +18948,15 @@
|
||||
}
|
||||
},
|
||||
"terser-webpack-plugin": {
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.4.tgz",
|
||||
"integrity": "sha512-U4mACBHIegmfoEe5fdongHESNJWqsGU+W0S/9+BmYGVQDw1+c2Ow05TpMhxjPK1sRb7cuYq1BPl1e5YHJMTCqA==",
|
||||
"version": "1.4.5",
|
||||
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz",
|
||||
"integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==",
|
||||
"requires": {
|
||||
"cacache": "^12.0.2",
|
||||
"find-cache-dir": "^2.1.0",
|
||||
"is-wsl": "^1.1.0",
|
||||
"schema-utils": "^1.0.0",
|
||||
"serialize-javascript": "^3.1.0",
|
||||
"serialize-javascript": "^4.0.0",
|
||||
"source-map": "^0.6.1",
|
||||
"terser": "^4.1.2",
|
||||
"webpack-sources": "^1.4.0",
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"@material-ui/icons": "^4.5.1",
|
||||
"@material-ui/styles": "^4.5.2",
|
||||
"@use-it/interval": "^0.1.3",
|
||||
"class-transformer": "^0.3.1",
|
||||
"class-transformer": "^0.3.1",
|
||||
"create-react-app": "^2.0.3",
|
||||
"cytoscape": "^3.11.0",
|
||||
"cytoscape-clipboard": "^2.2.1",
|
||||
@@ -54,6 +54,7 @@
|
||||
"shellwords": "^0.1.1",
|
||||
"simplebar": "^4.2.3",
|
||||
"styled-components": "^4.4.0",
|
||||
"webpack": "^4.42.0",
|
||||
"websocket": "^1.0.30",
|
||||
"yaml": "^1.7.2",
|
||||
"yamljs": "^0.3.0",
|
||||
|
||||
+101
-11
@@ -47,6 +47,7 @@ const Admin = (props) => {
|
||||
const [selectedUserModalOpen, setSelectedUserModalOpen] = React.useState(false)
|
||||
const [selectedAuthentication, setSelectedAuthentication] = React.useState({})
|
||||
const [selectedAuthenticationModalOpen, setSelectedAuthenticationModalOpen] = React.useState(false)
|
||||
const [showArchived, setShowArchived] = React.useState(false)
|
||||
|
||||
const alert = useAlert()
|
||||
|
||||
@@ -129,7 +130,8 @@ const Admin = (props) => {
|
||||
if (responseJson["success"] === false) {
|
||||
alert.error("Failed setting new password")
|
||||
} else {
|
||||
alert.success("Changed password!")
|
||||
alert.success("Successfully password!")
|
||||
setSelectedUserModalOpen(false)
|
||||
}
|
||||
}),
|
||||
)
|
||||
@@ -169,7 +171,6 @@ const Admin = (props) => {
|
||||
}
|
||||
|
||||
const submitUser = (data) => {
|
||||
// FIXME - add some check here ROFL
|
||||
console.log("INPUT: ", data)
|
||||
|
||||
// Just use this one?
|
||||
@@ -200,13 +201,21 @@ const Admin = (props) => {
|
||||
});
|
||||
}
|
||||
|
||||
const deleteEnvironment = (name) => {
|
||||
// Horrible frontend fix for environments
|
||||
const setDefaultEnvironment = (name) => {
|
||||
// FIXME - add some check here ROFL
|
||||
alert.info("Deleting environment " + name)
|
||||
alert.info("Setting default env to " + name)
|
||||
var newEnv = []
|
||||
for (var key in environments) {
|
||||
if (environments[key].Name == name) {
|
||||
continue
|
||||
if (environments[key].archived) {
|
||||
alert.error("Can't set archived to default")
|
||||
return
|
||||
}
|
||||
|
||||
environments[key].default = true
|
||||
} else if (environments[key].default == true && environments[key].name !== name) {
|
||||
environments[key].default = false
|
||||
}
|
||||
|
||||
newEnv.push(environments[key])
|
||||
@@ -226,6 +235,7 @@ const Admin = (props) => {
|
||||
response.json().then(responseJson => {
|
||||
if (responseJson["success"] === false) {
|
||||
alert.error(responseJson.reason)
|
||||
getEnvironments()
|
||||
} else {
|
||||
setLoginInfo("")
|
||||
setModalOpen(false)
|
||||
@@ -233,14 +243,60 @@ const Admin = (props) => {
|
||||
}
|
||||
}),
|
||||
)
|
||||
//.catch(error => {
|
||||
// console.log("Error in userdata: ", error)
|
||||
//});
|
||||
.catch(error => {
|
||||
console.log("Error in backend data: ", error)
|
||||
})
|
||||
}
|
||||
|
||||
const deleteEnvironment = (name) => {
|
||||
// FIXME - add some check here ROFL
|
||||
alert.info("Deleting environment " + name)
|
||||
var newEnv = []
|
||||
for (var key in environments) {
|
||||
if (environments[key].Name == name) {
|
||||
if (environments[key].default) {
|
||||
alert.info("Can't delete the default environment")
|
||||
return
|
||||
}
|
||||
environments[key].archived = true
|
||||
}
|
||||
|
||||
newEnv.push(environments[key])
|
||||
}
|
||||
|
||||
// Just use this one?
|
||||
const url = globalUrl + '/api/v1/setenvironments';
|
||||
fetch(url, {
|
||||
method: 'PUT',
|
||||
credentials: "include",
|
||||
body: JSON.stringify(newEnv),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
.then(response =>
|
||||
response.json().then(responseJson => {
|
||||
if (responseJson["success"] === false) {
|
||||
alert.error(responseJson.reason)
|
||||
getEnvironments()
|
||||
} else {
|
||||
setLoginInfo("")
|
||||
setModalOpen(false)
|
||||
getEnvironments()
|
||||
}
|
||||
}),
|
||||
)
|
||||
.catch(error => {
|
||||
console.log("Error when deleting: ", error)
|
||||
})
|
||||
}
|
||||
|
||||
const submitEnvironment = (data) => {
|
||||
// FIXME - add some check here ROFL
|
||||
environments.push({ "name": data.environment, "type": "onprem" })
|
||||
environments.push({
|
||||
"name": data.environment,
|
||||
"type": "onprem",
|
||||
})
|
||||
|
||||
// Just use this one?
|
||||
var baseurl = globalUrl
|
||||
@@ -257,6 +313,7 @@ const Admin = (props) => {
|
||||
response.json().then(responseJson => {
|
||||
if (responseJson["success"] === false) {
|
||||
setLoginInfo("Error in input: " + responseJson.reason)
|
||||
getEnvironments()
|
||||
} else {
|
||||
setLoginInfo("")
|
||||
setModalOpen(false)
|
||||
@@ -342,7 +399,6 @@ const Admin = (props) => {
|
||||
return response.json()
|
||||
})
|
||||
.then((responseJson) => {
|
||||
console.log(responseJson)
|
||||
setEnvironments(responseJson)
|
||||
})
|
||||
.catch(error => {
|
||||
@@ -934,6 +990,7 @@ const Admin = (props) => {
|
||||
</div>
|
||||
: null
|
||||
|
||||
console.log("Environments: ", environments)
|
||||
const environmentView = curTab === 2 ?
|
||||
<div>
|
||||
<div style={{marginTop: 20, marginBottom: 20,}}>
|
||||
@@ -967,12 +1024,29 @@ const Admin = (props) => {
|
||||
primary="Orborus running (TBD)"
|
||||
style={{minWidth: 200, maxWidth: 200}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary="Default"
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary="Actions"
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary="Archived"
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
/>
|
||||
</ListItem>
|
||||
{environments === undefined ? null : environments.map(environment => {
|
||||
if (!showArchived && environment.archived) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (environment.archived === undefined) {
|
||||
getEnvironments()
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
@@ -983,9 +1057,25 @@ const Admin = (props) => {
|
||||
primary={"TBD"}
|
||||
style={{minWidth: 200, maxWidth: 200, overflow: "hidden"}}
|
||||
/>
|
||||
<ListItemText>
|
||||
<ListItemText
|
||||
style={{minWidth: 150, maxWidth: 150, overflow: "hidden"}}
|
||||
primary={environment.default ? "true" : null}
|
||||
>
|
||||
{environment.default ?
|
||||
null
|
||||
:
|
||||
<Button variant="outlined" style={{borderRadius: "0px"}} onClick={() => setDefaultEnvironment(environment.Name)} color="primary">Set default</Button>
|
||||
}
|
||||
</ListItemText>
|
||||
<ListItemText
|
||||
style={{minWidth: 150, maxWidth: 150, overflow: "hidden"}}
|
||||
>
|
||||
<Button variant="outlined" style={{borderRadius: "0px"}} onClick={() => deleteEnvironment(environment.Name)} color="primary">Delete</Button>
|
||||
</ListItemText>
|
||||
<ListItemText
|
||||
style={{minWidth: 150, maxWidth: 150, overflow: "hidden"}}
|
||||
primary={environment.archived.toString()}
|
||||
/>
|
||||
</ListItem>
|
||||
)
|
||||
})}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -20,6 +20,7 @@ import Tooltip from '@material-ui/core/Tooltip';
|
||||
import CheckCircleIcon from '@material-ui/icons/CheckCircle';
|
||||
import Breadcrumbs from '@material-ui/core/Breadcrumbs';
|
||||
import AppsIcon from '@material-ui/icons/Apps';
|
||||
import CircularProgress from '@material-ui/core/CircularProgress';
|
||||
|
||||
import ErrorOutline from '@material-ui/icons/ErrorOutline';
|
||||
import { useAlert } from "react-alert";
|
||||
@@ -210,6 +211,7 @@ const AppCreator = (props) => {
|
||||
const [, setBasedata] = React.useState({})
|
||||
const [actions, setActions] = useState([])
|
||||
const [errorCode, setErrorCode] = useState("")
|
||||
const [appBuilding, setAppBuilding] = useState(false)
|
||||
|
||||
//const [actions, setActions] = useState([{
|
||||
// "name": "Get workflows",
|
||||
@@ -279,9 +281,9 @@ const AppCreator = (props) => {
|
||||
return response.json()
|
||||
})
|
||||
.then((responseJson) => {
|
||||
setIsAppLoaded(true)
|
||||
if (!responseJson.success) {
|
||||
alert.error("Failed to get the app")
|
||||
setIsAppLoaded(true)
|
||||
} else {
|
||||
const data = JSON.parse(responseJson.body)
|
||||
parseIncomingOpenapiData(data)
|
||||
@@ -365,6 +367,8 @@ const AppCreator = (props) => {
|
||||
var firstUrl = data.servers[0].url
|
||||
if (firstUrl.endsWith("/")) {
|
||||
setBaseUrl(firstUrl.slice(0, firstUrl.length-1))
|
||||
} else {
|
||||
setBaseUrl(firstUrl)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -378,9 +382,6 @@ const AppCreator = (props) => {
|
||||
securitySchemes = data.components.securitySchemes
|
||||
}
|
||||
|
||||
|
||||
console.log(data)
|
||||
|
||||
// FIXME - headers?
|
||||
var newActions = []
|
||||
var wordlist = {}
|
||||
@@ -398,7 +399,6 @@ const AppCreator = (props) => {
|
||||
"errors": [],
|
||||
}
|
||||
|
||||
|
||||
for (var key in methodvalue.parameters) {
|
||||
const parameter = methodvalue.parameters[key]
|
||||
if (parameter.in === "query") {
|
||||
@@ -520,11 +520,13 @@ const AppCreator = (props) => {
|
||||
}
|
||||
|
||||
setActions(newActions)
|
||||
setIsAppLoaded(true)
|
||||
}
|
||||
|
||||
// Saving the app that's been configured.
|
||||
const submitApp = () => {
|
||||
alert.info("Uploading and building app " + name)
|
||||
setAppBuilding(true)
|
||||
setErrorCode("")
|
||||
|
||||
// Format the information
|
||||
@@ -718,6 +720,7 @@ const AppCreator = (props) => {
|
||||
if (authenticationOption === "API key") {
|
||||
if (parameterName.length === 0) {
|
||||
alert.error("A field name for the APIkey must be defined")
|
||||
setAppBuilding(false)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -757,6 +760,7 @@ const AppCreator = (props) => {
|
||||
// throw new Error("NOT 200 :O")
|
||||
//}
|
||||
|
||||
setAppBuilding(false)
|
||||
return response.json()
|
||||
})
|
||||
.then((responseJson) => {
|
||||
@@ -1570,7 +1574,22 @@ const AppCreator = (props) => {
|
||||
margin="normal"
|
||||
variant="outlined"
|
||||
value={name}
|
||||
onChange={e => setName(e.target.value)}
|
||||
onChange={e => {
|
||||
const invalid = ["#", ":", "."]
|
||||
for (var key in invalid) {
|
||||
if (e.target.value.includes(invalid[key])) {
|
||||
alert.error("Can't use "+invalid[key]+" in name")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (e.target.value.length > 100) {
|
||||
alert.error("Choose a shorter name.")
|
||||
return
|
||||
}
|
||||
|
||||
setName(e.target.value)
|
||||
}}
|
||||
color="primary"
|
||||
InputProps={{
|
||||
style:{
|
||||
@@ -1590,12 +1609,12 @@ const AppCreator = (props) => {
|
||||
style={{flex: "1", marginTop: "5px", marginRight: "15px", backgroundColor: inputColor}}
|
||||
fullWidth={true}
|
||||
type="name"
|
||||
id="outlined-with-placeholder"
|
||||
id="outlined-with-placeholder"
|
||||
margin="normal"
|
||||
variant="outlined"
|
||||
placeholder="A description for the service"
|
||||
value={description}
|
||||
onChange={e => setDescription(e.target.value)}
|
||||
onChange={e => setDescription(e.target.value)}
|
||||
InputProps={{
|
||||
classes: {
|
||||
notchedOutline: classes.notchedOutline,
|
||||
@@ -1691,10 +1710,10 @@ const AppCreator = (props) => {
|
||||
{testView}
|
||||
*/}
|
||||
|
||||
<Button color="primary" variant="contained" style={{borderRadius: "0px", marginTop: "30px", height: "50px",}} onClick={() => {
|
||||
<Button disabled={appBuilding} color="primary" variant="contained" style={{borderRadius: "0px", marginTop: "30px", height: "50px",}} onClick={() => {
|
||||
submitApp()
|
||||
}}>
|
||||
Save
|
||||
{appBuilding ? <CircularProgress /> : "Save"}
|
||||
</Button>
|
||||
{errorCode.length > 0 ? `Error: ${errorCode}` : null}
|
||||
</Paper>
|
||||
|
||||
@@ -16,6 +16,7 @@ import Switch from '@material-ui/core/Switch';
|
||||
|
||||
import CircularProgress from '@material-ui/core/CircularProgress';
|
||||
import CachedIcon from '@material-ui/icons/Cached';
|
||||
import GetAppIcon from '@material-ui/icons/GetApp';
|
||||
import EditIcon from '@material-ui/icons/Edit';
|
||||
import MoreVertIcon from '@material-ui/icons/MoreVert';
|
||||
import PlayArrowIcon from '@material-ui/icons/PlayArrow';
|
||||
@@ -126,14 +127,15 @@ const Workflows = (props) => {
|
||||
color: "#ffffff",
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
maxWidth: "1768px",
|
||||
minWidth: 1366,
|
||||
maxWidth: 1766,
|
||||
margin: "auto",
|
||||
maxHeight: "90vh",
|
||||
}
|
||||
|
||||
const emptyWorkflowStyle = {
|
||||
paddingTop: "200px",
|
||||
width: "1024px",
|
||||
width: 1024,
|
||||
margin: "auto",
|
||||
}
|
||||
|
||||
@@ -263,6 +265,12 @@ const Workflows = (props) => {
|
||||
return new Promise((resolve) => setTimeout(resolve, time));
|
||||
}
|
||||
|
||||
const exportAllWorkflows = () => {
|
||||
for (var key in workflows) {
|
||||
exportWorkflow(workflows[key])
|
||||
}
|
||||
}
|
||||
|
||||
const exportWorkflow = (data) => {
|
||||
console.log("export")
|
||||
let dataStr = JSON.stringify(data)
|
||||
@@ -364,9 +372,9 @@ const Workflows = (props) => {
|
||||
}}>
|
||||
<div style={{marginLeft: "10px", marginTop: "5px", marginBottom: "5px", width: boxWidth, backgroundColor: boxColor}}>
|
||||
</div>
|
||||
<Grid container style={{margin: "10px 10px 10px 10px", flex: "1"}}>
|
||||
<Grid container style={{margin: "10px 10px 10px 10px", flex: 1}}>
|
||||
<Grid style={{display: "flex", flexDirection: "column", width: "100%"}}>
|
||||
<Grid item style={{flex: "1", display: "flex"}}>
|
||||
<Grid item style={{flex: 1, display: "flex"}}>
|
||||
<div style={{flex: "10",}} onClick={() => {
|
||||
if (selectedWorkflow.id !== data.id) {
|
||||
setSelectedWorkflow(data)
|
||||
@@ -418,7 +426,7 @@ const Workflows = (props) => {
|
||||
</Menu>
|
||||
</div>
|
||||
</Grid>
|
||||
<div style={{display: "flex", flex: "1"}} onClick={() => {
|
||||
<div style={{display: "flex", flex: 1}} onClick={() => {
|
||||
if (selectedWorkflow.id !== data.id) {
|
||||
setSelectedWorkflow(data)
|
||||
getWorkflowExecution(data.id)
|
||||
@@ -468,13 +476,13 @@ const Workflows = (props) => {
|
||||
var results = data.results.length
|
||||
}
|
||||
return (
|
||||
<Paper square style={paperAppStyle} onClick={() => {
|
||||
<Paper key={data.id} square style={paperAppStyle} onClick={() => {
|
||||
setSelectedExecution(data)
|
||||
}}>
|
||||
<div style={{marginLeft: "10px", marginTop: "5px", marginBottom: "5px", width: boxWidth, backgroundColor: boxColor}} />
|
||||
<Grid container style={{margin: "10px 10px 10px 10px", flex: "1"}}>
|
||||
<Grid container style={{margin: "10px 10px 10px 10px", flex: 1}}>
|
||||
<Grid style={{display: "flex", flexDirection: "column", width: "100%"}}>
|
||||
<Grid item style={{flex: "1", display: "flex"}}>
|
||||
<Grid item style={{flex: 1, display: "flex"}}>
|
||||
<div style={{flex: "5"}}>
|
||||
<h3 style={{marginBottom: "0px", marginTop: "10px"}}><b>Status</b>: {data.status}</h3>
|
||||
Actions: {results}/{actions}
|
||||
@@ -681,7 +689,7 @@ const Workflows = (props) => {
|
||||
*/
|
||||
if (Object.getOwnPropertyNames(selectedExecution).length > 0 && selectedExecution.workflow.actions !== null) {
|
||||
return (
|
||||
<div>
|
||||
<div style={{overflowX: "hidden"}}>
|
||||
<div>
|
||||
<b>Status:</b> {selectedExecution.status}
|
||||
</div>
|
||||
@@ -843,7 +851,7 @@ const Workflows = (props) => {
|
||||
}
|
||||
|
||||
const modalView = modalOpen ?
|
||||
<Dialog modal
|
||||
<Dialog
|
||||
open={modalOpen}
|
||||
onClose={() => {setModalOpen(false)}}
|
||||
PaperProps={{
|
||||
@@ -910,9 +918,9 @@ const Workflows = (props) => {
|
||||
|
||||
|
||||
const viewSize = {
|
||||
workflowView: 1,
|
||||
executionsView: 1,
|
||||
executionResults: 2,
|
||||
workflowView: 4,
|
||||
executionsView: 3,
|
||||
executionResults: 4,
|
||||
}
|
||||
|
||||
const workflowViewStyle = {
|
||||
@@ -943,7 +951,14 @@ const Workflows = (props) => {
|
||||
</Button>
|
||||
</Tooltip>
|
||||
*/}
|
||||
<Tooltip color="primary" title={"Download / Import workflows"} placement="top">
|
||||
<Tooltip color="primary" title={`Download ALL workflows (${workflows.length})`} placement="top">
|
||||
<Button color="primary" style={{}} variant="text" onClick={() => {
|
||||
exportAllWorkflows()
|
||||
}}>
|
||||
<GetAppIcon />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip color="primary" title={"Import workflows"} placement="top">
|
||||
<Button color="primary" style={{}} variant="text" onClick={() => setLoadWorkflowsModalOpen(true)}>
|
||||
<CloudDownloadIcon />
|
||||
</Button>
|
||||
@@ -982,10 +997,10 @@ const Workflows = (props) => {
|
||||
</div>
|
||||
<div style={{flex: viewSize.executionResults, marginLeft: "10px", marginRight: "10px", minWidth: "33%"}}>
|
||||
<div style={{display: "flex"}}>
|
||||
<div style={{flex: "3"}}>
|
||||
<div style={{flex: "1"}}>
|
||||
<h2>Execution Timeline</h2>
|
||||
</div>
|
||||
<div style={{flex: "1"}}>
|
||||
<div style={{flex: 1}}>
|
||||
<FormControlLabel
|
||||
style={{color: "white", marginBottom: "0px", marginTop: "10px"}}
|
||||
label={<div style={{color: "white"}}>Collapse results</div>}
|
||||
@@ -1075,7 +1090,7 @@ const Workflows = (props) => {
|
||||
}
|
||||
|
||||
const workflowDownloadModalOpen = loadWorkflowsModalOpen ?
|
||||
<Dialog modal
|
||||
<Dialog
|
||||
open={loadWorkflowsModalOpen}
|
||||
onClose={() => {
|
||||
}}
|
||||
|
||||
+18
-7
@@ -7,7 +7,6 @@ The Docker setup is done with docker-compose and is a single command to get set
|
||||
**PS: if you're setting up Shuffle on Windows, go to the next step (Windows Docker setup)**
|
||||
|
||||
1. Make sure you have Docker and [docker-compose](https://docs.docker.com/compose/install/) installed.
|
||||
|
||||
2. Run docker-compose.
|
||||
```
|
||||
git clone https://github.com/frikky/Shuffle
|
||||
@@ -20,7 +19,7 @@ When you're done, skip to the "After installation" step below.
|
||||
## Windows Docker setup
|
||||
This step is for setting up with Docker on windows from scratch.
|
||||
|
||||
1. Make sure you have [Docker](https://docs.docker.com/docker-for-windows/install/) and [docker-compose](https://docs.docker.com/compose/install/) installed
|
||||
1. Make sure you have [Docker](https://docs.docker.com/docker-for-windows/install/) and [docker-compose](https://docs.docker.com/compose/install/) installed. WSL2 may be required.
|
||||
2. Go to https://github.com/frikky/shuffle/releases and download the latest .zip release (or install git)
|
||||
3. Unzip the folder and enter it
|
||||
4. Open the .env file and change the line with "OUTER_HOSTNAME" to contain your IP:
|
||||
@@ -84,14 +83,16 @@ docker-compose up
|
||||
Related issue: #47
|
||||
|
||||
## Local development installation
|
||||
Frontend - requires [npm](https://nodejs.org/en/download/)/[yarn](https://yarnpkg.com/lang/en/docs/install/#debian-stable)/your preferred manager. Runs independently from backend - edit frontend/src/App.yaml (line 44~) from window.location.origin to http://YOUR IP:5001
|
||||
**Frontend - ReactJS /w cytoscape**
|
||||
http://localhost:3000 - Requires [npm](https://nodejs.org/en/download/)/[yarn](https://yarnpkg.com/lang/en/docs/install/#debian-stable)/your preferred manager. Runs independently from backend.
|
||||
```bash
|
||||
cd frontend
|
||||
npm i
|
||||
npm start
|
||||
```
|
||||
|
||||
Backend - API calls - requires [>=go1.13](https://golang.org/dl/)
|
||||
**Backend - Golang**
|
||||
http://localhost:5001 - REST API - requires [>=go1.13](https://golang.org/dl/)
|
||||
```bash
|
||||
export DATASTORE_EMULATOR_HOST=0.0.0.0:8000
|
||||
cd backend/go-app
|
||||
@@ -99,16 +100,26 @@ go build
|
||||
go run *.go
|
||||
```
|
||||
|
||||
Database - Datastore:
|
||||
**Database - Datastore**
|
||||
Based on Google datastore
|
||||
```
|
||||
docker run -p 8000:8000 google/cloud-sdk gcloud beta emulators datastore start --project=shuffle --host-port 0.0.0.0:8000 --no-store-on-disk
|
||||
```
|
||||
|
||||
Orborus - Execution of Workflows:
|
||||
PS: This requires some specific environment variables.
|
||||
**Orborus**
|
||||
Execution of Workflows:
|
||||
PS: This requires some specific environment variables
|
||||
```
|
||||
cd functions/onprem/orborus
|
||||
go run orborus.go
|
||||
```
|
||||
Environments:
|
||||
```
|
||||
export ORG_ID=Shuffle
|
||||
export ENVIRONMENT_NAME=Shuffle
|
||||
export BASE_URL=http://YOUR-IP:5001
|
||||
export DOCKER_API_VERSION=1.40
|
||||
export SHUFFLE_PASS_WORKER_PROXY=${SHUFFLE_PASS_WORKER_PROXY}
|
||||
```
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user