diff --git a/backend/go-app/go.mod b/backend/go-app/go.mod index 6b3c8108..c018e260 100644 --- a/backend/go-app/go.mod +++ b/backend/go-app/go.mod @@ -2,7 +2,7 @@ module shuffle go 1.22.2 -//replace github.com/shuffle/shuffle-shared => ../../../shuffle-shared +replace github.com/shuffle/shuffle-shared => ../../../shuffle-shared require ( cloud.google.com/go/datastore v1.15.0 @@ -19,7 +19,7 @@ require ( github.com/h2non/filetype v1.1.3 github.com/satori/go.uuid v1.2.0 github.com/shuffle/shuffle-shared v0.8.0 - golang.org/x/crypto v0.31.0 + golang.org/x/crypto v0.32.0 google.golang.org/api v0.176.1 google.golang.org/grpc v1.68.1 gopkg.in/src-d/go-git.v4 v4.13.1 @@ -118,11 +118,11 @@ require ( go.opentelemetry.io/otel/trace v1.33.0 // indirect go4.org v0.0.0-20201209231011-d4a079459e60 // indirect golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.33.0 // indirect - golang.org/x/oauth2 v0.19.0 // indirect + golang.org/x/net v0.34.0 // indirect + golang.org/x/oauth2 v0.23.0 // indirect golang.org/x/sync v0.10.0 // indirect - golang.org/x/sys v0.28.0 // indirect - golang.org/x/term v0.27.0 // indirect + golang.org/x/sys v0.29.0 // indirect + golang.org/x/term v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect diff --git a/backend/go-app/go.sum b/backend/go-app/go.sum index 334170e4..5135bcff 100644 --- a/backend/go-app/go.sum +++ b/backend/go-app/go.sum @@ -350,6 +350,9 @@ github.com/sendgrid/sendgrid-go v3.14.0+incompatible/go.mod h1:QRQt+LX/NmgVEvmdR github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY= github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M= github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0= @@ -429,6 +432,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -485,6 +490,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -532,12 +539,16 @@ golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= +golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= +golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/backend/go-app/main.go b/backend/go-app/main.go index e1f0defa..dfdce781 100755 --- a/backend/go-app/main.go +++ b/backend/go-app/main.go @@ -3079,8 +3079,9 @@ func buildSwaggerApp(resp http.ResponseWriter, body []byte, user shuffle.User, s return } - // FIXME: Check whether it's in use. - if user.Id != app.Owner && user.Role != "admin" { + if user.Id == app.Owner || (user.Role == "admin" && user.ActiveOrg.Id == app.ReferenceOrg) || shuffle.ArrayContains(app.Contributors, user.Id) { + log.Printf("[DEBUG] Editing app %s with user %s (%s) in org %s", test.Id, user.Username, user.Id, user.ActiveOrg.Id) + } else { log.Printf("[WARNING] Wrong user (%s) for app %s when verifying swagger", user.Username, app.Name) resp.WriteHeader(403) resp.Write([]byte(`{"success": false, "reason": "You don't have permissions to edit this app. Contact support@shuffler.io if this persists."}`)) @@ -3154,7 +3155,18 @@ func buildSwaggerApp(resp http.ResponseWriter, body []byte, user shuffle.User, s } } - api.Owner = user.Id + if api.Owner == "" { + api.Owner = user.Id + } + + if len(api.ReferenceOrg) == 0 { + api.ReferenceOrg = user.ActiveOrg.Id + } + + if len(test.Image) > 0 { + api.SmallImage = test.Image + api.LargeImage = test.Image + } err = shuffle.DumpApi(basePath, api) if err != nil { @@ -3279,6 +3291,10 @@ func buildSwaggerApp(resp http.ResponseWriter, body []byte, user shuffle.User, s Body: string(body), } + if !shuffle.ArrayContains(api.Contributors, user.Id) { + api.Contributors = append(api.Contributors, user.Id) + } + log.Printf("[INFO] API LENGTH FOR %s: %d, ID: %s", api.Name, len(parsed.Body), newmd5) // FIXME: Might cause versioning issues if we re-use the same!! // FIXME: Need a way to track different versions of the same app properly. @@ -5185,6 +5201,16 @@ func initHandlers() { r.HandleFunc("/api/v1/hooks/{key}/delete", shuffle.HandleDeleteHook).Methods("DELETE", "OPTIONS") r.HandleFunc("/api/v1/hooks/{key}", shuffle.HandleDeleteHook).Methods("DELETE", "OPTIONS") + // This structure is horrendous. Needs fixing after we got the prototype up + r.HandleFunc("/api/v1/detections", shuffle.HandleListDetectionCategories).Methods("GET", "OPTIONS") + r.HandleFunc("/api/v1/detections/{detectionType}/connect", shuffle.HandleDetectionAutoConnect).Methods("GET", "OPTIONS") + r.HandleFunc("/api/v1/detections/{detection_type}", shuffle.HandleGetDetectionRules).Methods("GET", "OPTIONS") + r.HandleFunc("/api/v1/detections/{detection_type}/selected_rules/{action}", shuffle.HandleFolderToggle).Methods("PUT", "OPTIONS") + + r.HandleFunc("/api/v1/detections/{triggerId}/selected_rules", shuffle.HandleGetSelectedRules).Methods("GET", "OPTIONS") + r.HandleFunc("/api/v1/detections/{triggerId}/selected_rules/save", shuffle.HandleSaveSelectedRules).Methods("POST", "OPTIONS") + r.HandleFunc("/api/v1/detections/{detection_type}/{fileId}/{action}", shuffle.HandleToggleRule).Methods("PUT", "OPTIONS") + // OpenAPI configuration r.HandleFunc("/api/v1/verify_swagger", verifySwagger).Methods("POST", "OPTIONS") r.HandleFunc("/api/v1/verify_openapi", verifySwagger).Methods("POST", "OPTIONS") diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 8c0e8870..34a952e6 100755 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -648,18 +648,58 @@ const App = (message, props) => { /> } /> - - } - /> + + } + /> + + } + /> + + } + /> + + } + /> { hitsPerPage={5} searchQuery={searchQuery} globalUrl={globalUrl} - isCloud={isCloud} + isCloud={isCloud !== true} userdata={userdata} getAppAuthentication={getAppAuthentication} /> @@ -878,6 +878,7 @@ const AppAuthTab = memo((props) => { style={{ color: '#1a1a1a', textTransform: 'none', backgroundColor: "#FF8444", marginLeft:"auto", borderRadius: 4,fontSize: 16, minWidth: 162, height: 40, boxShadow:'none', }} variant="contained" color="primary" + disabled={!isCloud} onClick={() => setShowAppModal(true)} > Add App Auth diff --git a/frontend/src/components/AppFramework.jsx b/frontend/src/components/AppFramework.jsx index c65cf1cf..d6fc1f42 100644 --- a/frontend/src/components/AppFramework.jsx +++ b/frontend/src/components/AppFramework.jsx @@ -198,7 +198,7 @@ export const findSpecificApp = (framework, inputcategory) => { id: "", } } else { - console.log("findSpecificApp: unknown category: ", category) + //console.log("findSpecificApp: unknown category: ", category) } return null diff --git a/frontend/src/components/AppSearchButtons.jsx b/frontend/src/components/AppSearchButtons.jsx index 81274ee0..cf9741cb 100644 --- a/frontend/src/components/AppSearchButtons.jsx +++ b/frontend/src/components/AppSearchButtons.jsx @@ -88,7 +88,7 @@ const AppSearchButtons = (props) => { const foundApp = findSpecificApp(appFramework, appType) if (foundApp === undefined || foundApp === null) { - console.log("AppSearchButtons: App not found in appFramework: " + appType) + //console.log("AppSearchButtons: App not found in appFramework: " + appType) return null } diff --git a/frontend/src/components/ParsedAction.jsx b/frontend/src/components/ParsedAction.jsx index e035724d..4732efc2 100755 --- a/frontend/src/components/ParsedAction.jsx +++ b/frontend/src/components/ParsedAction.jsx @@ -361,7 +361,7 @@ const ParsedAction = (props) => { } if (keyorder.join(",") !== newkeyorder.join(",")) { - console.log("KEYORDER CHANGED! DID ACTION AS WELL?", keyorder, newkeyorder) + //console.log("KEYORDER CHANGED! DID ACTION AS WELL?", keyorder, newkeyorder) setSelectedActionParameters(newparams) selectedAction.parameters = newparams @@ -3658,6 +3658,12 @@ const ParsedAction = (props) => { ); + if (selectedApp.name === "email") { + //hideBody = false + showButtonField = false + hideBodyButtonValue = null + } + if ((multiline === undefined || multiline === false) && ((data?.autocompleted === true || data?.field_active === true) || data.name.startsWith("${") && data.name.endsWith("}"))) { multiline = true diff --git a/frontend/src/views/AngularWorkflow.jsx b/frontend/src/views/AngularWorkflow.jsx index 3904b15f..bdbaf1c2 100755 --- a/frontend/src/views/AngularWorkflow.jsx +++ b/frontend/src/views/AngularWorkflow.jsx @@ -2715,10 +2715,12 @@ const AngularWorkflow = (defaultprops) => { return newExample } + /* for (var i = 0; i < found.length; i++) { //newExample = newExample.replace(found[i], "REQUIRED") newExample = newExample.replace(found[i], "REPLACE_ME") } + */ return newExample } @@ -7116,7 +7118,6 @@ const AngularWorkflow = (defaultprops) => { data: newcybranch, }; - console.log("SHOULD STITCH WITH STARTNODE"); cy.add(edgeToBeAdded); } @@ -12416,13 +12417,7 @@ const AngularWorkflow = (defaultprops) => { // Get parent nodes and their data if (selectedEdge) { - - let nodeId; - if (type === "source") { - nodeId = selectedEdge.source; - } else if (type === "destination") { - nodeId = selectedEdge.target; - } + const nodeId = selectedEdge.target; const node = cy.getElementById(nodeId); if (node?.length > 0) { diff --git a/frontend/src/views/Apps2.jsx b/frontend/src/views/Apps2.jsx index c78eabe6..e910417c 100644 --- a/frontend/src/views/Apps2.jsx +++ b/frontend/src/views/Apps2.jsx @@ -52,12 +52,11 @@ const searchClient = algoliasearch( const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl, deactivatedIndexes, currTab, handleAppClick, leftSideBarOpenByClick, userdata, fetchApps, appsToShow, setAppsToShow, setUserApps, }) => { const navigate = useNavigate(); const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io" || window.location.host === "localhost:3000"; - const appUrl = isCloud ? `/apps/${data.id}` : `https://shuffler.io/apps/${data.id}`; + //const appUrl = isCloud ? `/apps/${data.id}` : `https://shuffler.io/apps/${data.id}`; + const appUrl = `/apps/${data.id}` - var canEditApp = userdata?.support || - userdata?.id === data?.owner || - (userdata?.admin === "true" && userdata?.active_org?.id === data?.reference_org) || - data?.contributors?.includes(userdata?.id) + var canEditApp = userdata?.support || userdata?.id === data?.owner || + (userdata?.admin === "true" && userdata?.active_org?.id === data?.reference_org) || data?.contributors?.includes(userdata?.id) const paperStyle = { backgroundColor: mouseHoverIndex === index ? "rgba(26, 26, 26, 1)" : "#212121", @@ -71,7 +70,7 @@ const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl, boxShadow: "0px 0px 10px 0px rgba(0, 0, 0, 0.1)", marginBottom: 20, transition: "width 0.3s ease", - }; + } return ( @@ -133,6 +132,7 @@ const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl, margin: "12px 0", fontFamily: theme?.typography?.fontFamily, }}> +
+
{data.name.replace(/_/g, ' ').replace(/\b\w/g, char => char.toUpperCase())}
+
{data.categories ? data.categories.join(", ") : "NA"}
+
))}
+ {/* Deactivate button */} {(currTab === 0 || currTab === 1) && !deactivatedIndexes.includes(index) && mouseHoverIndex === index && data.generated === true && (
) } +
)} +
{hoverEffect === index && (
- {allActivatedAppIds && allActivatedAppIds.includes(data.objectID) ? ( + {allActivatedAppIds && allActivatedAppIds?.includes(data.objectID) ? ( + ) : ( +