frontend
frontend copied to clipboard
Display when updated version are available in Dependency Graph
Current Behavior
On the Components view we have the convenient flag to say when a newer version is available. Most Components are transitive and much as we might like to update them, we don't have any easy way to do so. Nowhere in the UI is there a way to see all the direct dependencies along with a highlight of the ones that we can update.
Proposed Behavior
I can see two ways the UI could be enhanced to provide this information:
- Have a flag on the Components view to only show direct dependencies of the project.
- Put the version flag onto the Dependency Graph.
I would prefer not to have the green triangle (anywhere - I don't think an OK symbol should ever be a triangle with an exclamation mark in it, and the colours chosen are not helpful for green/yellow colour blindness).
Checklist
- [X] I have read and understand the contributing guidelines
- [X] I have checked the existing issues for whether this enhancement was already requested
@walterdeboer had the same thought and implemented https://github.com/DependencyTrack/dependency-track/pull/2568. It's already merged to master
and will be shipped with Dependency-Track v4.9.
You can give it a spin using our snapshot
builds of both API server and frontend, and let us know if it fulfills your request!
The screenshots look great, but unfortunately when I try to run the snapshot image the backed is failing. I don't think this is relevant to that change, but means I can't test it today. The exception is:
2023-07-07 08:20:52,704 ERROR [Datastore] Error thrown executing ALTER TABLE VULNERABILITY ADD COLUMN OWASPRRTECHNICALIMPACTSCORE DECIMAL(19,1) NULL : General error: "java.lang.NullPointerException: Cannot read field ""streamStoreId"" because ""<local11>"" is null"; SQL statement:
INSERT INTO "PUBLIC"."VULNERABILITY_COPY_3_0"("ID", "CREATED", "CREDITS", "CVSSV2BASESCORE", "CVSSV2EXPLOITSCORE", "CVSSV2IMPACTSCORE", "CVSSV2VECTOR", "CVSSV3BASESCORE", "CVSSV3EXPLOITSCORE", "CVSSV3IMPACTSCORE", "CVSSV3VECTOR", "CWES", "DESCRIPTION", "DETAIL", "EPSSPERCENTILE", "EPSSSCORE", "FRIENDLYVULNID", "PATCHEDVERSIONS", "PUBLISHED", "RECOMMENDATION", "REFERENCES", "SEVERITY", "SOURCE", "SUBTITLE", "TITLE", "UPDATED", "UUID", "VULNID", "VULNERABLEVERSIONS", "OWASPRRLIKELIHOODSCORE", "OWASPRRBUSINESSIMPACTSCORE", "OWASPRRVECTOR") OVERRIDING SYSTEM VALUE SELECT "ID", "CREATED", "CREDITS", "CVSSV2BASESCORE", "CVSSV2EXPLOITSCORE", "CVSSV2IMPACTSCORE", "CVSSV2VECTOR", "CVSSV3BASESCORE", "CVSSV3EXPLOITSCORE", "CVSSV3IMPACTSCORE", "CVSSV3VECTOR", "CWES", "DESCRIPTION", "DETAIL", "EPSSPERCENTILE", "EPSSSCORE", "FRIENDLYVULNID", "PATCHEDVERSIONS", "PUBLISHED", "RECOMMENDATION", "REFERENCES", "SEVERITY", "SOURCE", "SUBTITLE", "TITLE", "UPDATED", "UUID", "VULNID", "VULNERABLEVERSIONS", "OWASPRRLIKELIHOODSCORE", "OWASPRRBUSINESSIMPACTSCORE", "OWASPRRVECTOR" FROM "PUBLIC"."VULNERABILITY" [50000-214]
org.h2.jdbc.JdbcSQLNonTransientException: General error: "java.lang.NullPointerException: Cannot read field ""streamStoreId"" because ""<local11>"" is null"; SQL statement:
INSERT INTO "PUBLIC"."VULNERABILITY_COPY_3_0"("ID", "CREATED", "CREDITS", "CVSSV2BASESCORE", "CVSSV2EXPLOITSCORE", "CVSSV2IMPACTSCORE", "CVSSV2VECTOR", "CVSSV3BASESCORE", "CVSSV3EXPLOITSCORE", "CVSSV3IMPACTSCORE", "CVSSV3VECTOR", "CWES", "DESCRIPTION", "DETAIL", "EPSSPERCENTILE", "EPSSSCORE", "FRIENDLYVULNID", "PATCHEDVERSIONS", "PUBLISHED", "RECOMMENDATION", "REFERENCES", "SEVERITY", "SOURCE", "SUBTITLE", "TITLE", "UPDATED", "UUID", "VULNID", "VULNERABLEVERSIONS", "OWASPRRLIKELIHOODSCORE", "OWASPRRBUSINESSIMPACTSCORE", "OWASPRRVECTOR") OVERRIDING SYSTEM VALUE SELECT "ID", "CREATED", "CREDITS", "CVSSV2BASESCORE", "CVSSV2EXPLOITSCORE", "CVSSV2IMPACTSCORE", "CVSSV2VECTOR", "CVSSV3BASESCORE", "CVSSV3EXPLOITSCORE", "CVSSV3IMPACTSCORE", "CVSSV3VECTOR", "CWES", "DESCRIPTION", "DETAIL", "EPSSPERCENTILE", "EPSSSCORE", "FRIENDLYVULNID", "PATCHEDVERSIONS", "PUBLISHED", "RECOMMENDATION", "REFERENCES", "SEVERITY", "SOURCE", "SUBTITLE", "TITLE", "UPDATED", "UUID", "VULNID", "VULNERABLEVERSIONS", "OWASPRRLIKELIHOODSCORE", "OWASPRRBUSINESSIMPACTSCORE", "OWASPRRVECTOR" FROM "PUBLIC"."VULNERABILITY" [50000-214]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:554)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:477)
at org.h2.message.DbException.get(DbException.java:212)
at org.h2.message.DbException.convert(DbException.java:395)
at org.h2.command.Command.executeUpdate(Command.java:264)
at org.h2.command.ddl.AlterTableAlterColumn.execute(AlterTableAlterColumn.java:645)
at org.h2.command.ddl.AlterTableAlterColumn.cloneTableStructure(AlterTableAlterColumn.java:557)
at org.h2.command.ddl.AlterTableAlterColumn.copyData(AlterTableAlterColumn.java:339)
at org.h2.command.ddl.AlterTableAlterColumn.update(AlterTableAlterColumn.java:242)
at org.h2.command.CommandContainer.update(CommandContainer.java:169)
at org.h2.command.Command.executeUpdate(Command.java:252)
at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:252)
at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:223)
at org.datanucleus.store.rdbms.datasource.dbcp2.DelegatingStatement.execute(DelegatingStatement.java:194)
at org.datanucleus.store.rdbms.datasource.dbcp2.DelegatingStatement.execute(DelegatingStatement.java:194)
at org.datanucleus.store.rdbms.table.AbstractTable.executeDdlStatement(AbstractTable.java:799)
at org.datanucleus.store.rdbms.table.AbstractTable.executeDdlStatementList(AbstractTable.java:749)
at org.datanucleus.store.rdbms.table.TableImpl.validateColumns(TableImpl.java:235)
at org.datanucleus.store.rdbms.RDBMSStoreManager$ClassAdder.performTablesValidation(RDBMSStoreManager.java:3510)
at org.datanucleus.store.rdbms.RDBMSStoreManager$ClassAdder.run(RDBMSStoreManager.java:3024)
at org.datanucleus.store.rdbms.AbstractSchemaTransaction.execute(AbstractSchemaTransaction.java:118)
at org.datanucleus.store.rdbms.RDBMSStoreManager.createSchemaForClasses(RDBMSStoreManager.java:3866)
at org.datanucleus.store.schema.SchemaTool.createSchemaForClasses(SchemaTool.java:507)
at org.datanucleus.PersistenceNucleusContextImpl.initialiseSchema(PersistenceNucleusContextImpl.java:824)
at org.datanucleus.PersistenceNucleusContextImpl.initialise(PersistenceNucleusContextImpl.java:484)
at org.datanucleus.api.jdo.JDOPersistenceManagerFactory.freezeConfiguration(JDOPersistenceManagerFactory.java:865)
at org.datanucleus.api.jdo.JDOPersistenceManagerFactory.createPersistenceManagerFactory(JDOPersistenceManagerFactory.java:352)
at org.datanucleus.api.jdo.JDOPersistenceManagerFactory.getPersistenceManagerFactory(JDOPersistenceManagerFactory.java:275)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at javax.jdo.JDOHelper$16.run(JDOHelper.java:1975)
at java.base/java.security.AccessController.doPrivileged(Unknown Source)
at javax.jdo.JDOHelper.invoke(JDOHelper.java:1970)
at javax.jdo.JDOHelper.invokeGetPersistenceManagerFactoryOnImplementation(JDOHelper.java:1139)
at javax.jdo.JDOHelper.getPersistenceManagerFactory(JDOHelper.java:851)
at javax.jdo.JDOHelper.getPersistenceManagerFactory(JDOHelper.java:1109)
at javax.jdo.JDOHelper.getPersistenceManagerFactory(JDOHelper.java:969)
at org.dependencytrack.upgrade.UpgradeInitializer.createPersistenceManagerFactory(UpgradeInitializer.java:121)
at org.dependencytrack.upgrade.UpgradeInitializer.contextInitialized(UpgradeInitializer.java:68)
at org.eclipse.jetty.server.handler.ContextHandler.callContextInitialized(ContextHandler.java:1050)
at org.eclipse.jetty.servlet.ServletContextHandler.callContextInitialized(ServletContextHandler.java:624)
at org.eclipse.jetty.server.handler.ContextHandler.contextInitialized(ContextHandler.java:985)
at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:740)
at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:392)
at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1304)
at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:902)
at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:306)
at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:532)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:93)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:171)
at org.eclipse.jetty.server.Server.start(Server.java:470)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:89)
at org.eclipse.jetty.server.Server.doStart(Server.java:415)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:93)
at alpine.embedded.EmbeddedJettyServer.main(EmbeddedJettyServer.java:100)
Caused by: java.lang.NullPointerException: Cannot read field "streamStoreId" because "<local11>" is null
at org.h2.mvstore.db.LobStorageMap.copyLob(LobStorageMap.java:280)
at org.h2.value.ValueLob.copyToResult(ValueLob.java:291)
at org.h2.result.LocalResult.cloneLobs(LocalResult.java:357)
at org.h2.result.LocalResult.addRow(LocalResult.java:409)
at org.h2.command.query.Select.queryFlat(Select.java:730)
at org.h2.command.query.Select.queryWithoutCache(Select.java:833)
at org.h2.command.query.Query.queryWithoutCacheLazyCheck(Query.java:197)
at org.h2.command.query.Query.query(Query.java:512)
at org.h2.command.query.Query.query(Query.java:475)
at org.h2.command.dml.Insert.insertRows(Insert.java:199)
at org.h2.command.dml.Insert.update(Insert.java:135)
at org.h2.command.dml.DataChangeStatement.update(DataChangeStatement.java:74)
at org.h2.command.CommandContainer.update(CommandContainer.java:169)
at org.h2.command.Command.executeUpdate(Command.java:252)
... 53 more
Isn't that what we implemented already in one of last versions or do I misunderstand? There is a checkbox on the graph, allowing you to show outdated component status, which shows the icon in each graph node that has an outdated version.
I do think that there is a wee bit of work outstanding here.
Testing with 4.11 SNAPSHOT, there is indeed a checkbox on the main dependency graph (accessesd via "Dependency Graph" tab) and the checkbox works in this view.
However, there is no checkbox when one views a filtered graph for a specific component. If one has already ticked the checkbox on the main graph then this preference is respected in the component graph and the out-of-date icon is displayed. But one cannot toggle "in-situ", which is a bit annoying.
I would prefer not to have the green triangle (anywhere - I don't think an OK symbol should ever be a triangle with an exclamation mark in it, and the colours chosen are not helpful for green/yellow colour blindness).
The accessibility issue was mentioned in #311 (which has now been closed with some changes made) but it does seem that things can still be improved. Accessibility is something that has to be taken seriously if DT is to be used by government organisations, etc.