Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
d9c10a3
Change: Split targets query hooks into two modules
bjoernricks Oct 5, 2026
b9c267e
Change: Split users query hooks into two modules
bjoernricks Oct 5, 2026
c4a60c1
Change: Add Ticket clone and delete success messages to query hooks
bjoernricks Oct 5, 2026
559cca4
test: Update Group and Role query hook tests
bjoernricks Oct 5, 2026
60da0ac
Change: Add User clone and delete success messages to query hooks
bjoernricks Oct 5, 2026
8254800
Add query hooks for Target
bjoernricks Oct 5, 2026
2784fcd
Change: Allow to pass a response or the data directly to goToDetails
bjoernricks Oct 5, 2026
0359edc
Change: Use new target query hooks in TargetComponent
bjoernricks Oct 5, 2026
b274ff6
Change deletePortRange command to just delete the port range
bjoernricks Oct 6, 2026
db2e122
Add query hooks for port list handling
bjoernricks Oct 6, 2026
dee5670
Change: Adapt PortListComponent to use new port list query hooks
bjoernricks Oct 6, 2026
e0e2d8b
Add first query hooks for credentials
bjoernricks Oct 6, 2026
0383de3
Change: Use new port list and credential query hooks
bjoernricks Oct 6, 2026
211cdfb
test: Improve organization of query hook tests for users
bjoernricks Oct 6, 2026
1b41955
Update and fix TargetDetailsPage test
bjoernricks Oct 6, 2026
76e4085
Change: Split query hooks for agent groups into two modules
bjoernricks Oct 6, 2026
5bb8726
Change: Use useCloneMutation for all useClone* mutations
bjoernricks Oct 6, 2026
a3a116a
Change: Use useCreateMutation for all useCreate* mutations
bjoernricks Oct 6, 2026
fae6fe6
Change: Make input type of useDeleteMutation generic
bjoernricks Oct 6, 2026
4ddaffa
Change: Make inheritorId for deleting a user optional
bjoernricks Oct 6, 2026
acc7bbf
Change: Improve types for generic query hooks which have a success me…
bjoernricks Oct 6, 2026
573c5fd
Change: Update and improve existing query hooks
bjoernricks Oct 6, 2026
b80ca2a
Adapt components to query hook changes
bjoernricks Oct 6, 2026
483be75
Change: Split tag query hooks into two modules
bjoernricks Oct 7, 2026
da6d9ff
Change: Split agent query hooks into two modules
bjoernricks Oct 7, 2026
1fb4be5
Change: Split audit query hooks into two modules
bjoernricks Oct 7, 2026
3d8bfc5
Change: Split credential store query hooks into two modules
bjoernricks Oct 7, 2026
b7eb6f0
Change: Split oci image target query hooks into two modules
bjoernricks Oct 7, 2026
83481a7
Change: Split policy query hooks into two modules
bjoernricks Oct 7, 2026
140beb4
Change: Split web application target query hooks into two modules
bjoernricks Oct 7, 2026
999e6e8
Change WebAppliactionTargetCommand to return void from save method
bjoernricks Oct 7, 2026
f07bef8
Add type for CredentialStoreCommand verify params
bjoernricks Oct 7, 2026
dbca7e9
Improve credential store test expectations
bjoernricks Oct 7, 2026
d95c145
Change: Unify params and return values of single entity query hooks
bjoernricks Oct 7, 2026
fba6bb6
Change: Update importing a port list
bjoernricks Oct 7, 2026
0525f98
Update public/locales/gsa-it.json
bjoernricks Oct 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions public/locales/gsa-de.json
Original file line number Diff line number Diff line change
Expand Up @@ -1604,6 +1604,7 @@
"Port Counts: Total": "Portanzahl: Gesamt",
"Port Counts: UDP": "Portanzahl: UDP",
"Port List": "Portliste",
"Port List imported successfully.": "Portliste erfolgreich importiert.",
"Port List: {{name}}": "Portliste: {{name}}",
"Port Lists": "Portlisten",
"Port Lists Filter": "Portlisten-Filter",
Expand Down
1 change: 1 addition & 0 deletions public/locales/gsa-en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1604,6 +1604,7 @@
"Port Counts: Total": "Port Counts: Total",
"Port Counts: UDP": "Port Counts: UDP",
"Port List": "Port List",
"Port List imported successfully.": "Port List imported successfully.",
"Port List: {{name}}": "Port List: {{name}}",
"Port Lists": "Port Lists",
"Port Lists Filter": "Port Lists Filter",
Expand Down
2 changes: 2 additions & 0 deletions public/locales/gsa-it.json
Original file line number Diff line number Diff line change
Expand Up @@ -1604,6 +1604,8 @@
"Port Counts: Total": "Conteggi porte: Totale",
"Port Counts: UDP": "Conteggi porte: UDP",
"Port List": "Elenco porte",
"Port List imported successfully.": "Elenco porte importato con successo.",

"Port List: {{name}}": "Elenco porte: {{name}}",
"Port Lists": "Elenchi porte",
"Port Lists Filter": "Filtro elenchi porte",
Expand Down
1 change: 1 addition & 0 deletions public/locales/gsa-ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -1604,6 +1604,7 @@
"Port Counts: Total": "ポート数: 合計",
"Port Counts: UDP": "ポート数: UDP",
"Port List": "ポートリスト",
"Port List imported successfully.": "",
"Port List: {{name}}": "ポートリスト: {{name}}",
"Port Lists": "ポートリスト",
"Port Lists Filter": "ポートリストフィルター",
Expand Down
1 change: 1 addition & 0 deletions public/locales/gsa-zh_CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -1604,6 +1604,7 @@
"Port Counts: Total": "端口数量: 总数",
"Port Counts: UDP": "端口数量: UDP",
"Port List": "端口列表",
"Port List imported successfully.": "",
"Port List: {{name}}": "端口列表:{{name}}",
"Port Lists": "端口列表",
"Port Lists Filter": "端口列表筛选",
Expand Down
1 change: 1 addition & 0 deletions public/locales/gsa-zh_TW.json
Original file line number Diff line number Diff line change
Expand Up @@ -1604,6 +1604,7 @@
"Port Counts: Total": "",
"Port Counts: UDP": "",
"Port List": "連接埠清單",
"Port List imported successfully.": "",
"Port List: {{name}}": "",
"Port Lists": "連接埠清單",
"Port Lists Filter": "",
Expand Down
8 changes: 3 additions & 5 deletions src/gmp/commands/__tests__/port-list.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import PortListCommand, {FROM_FILE} from 'gmp/commands/port-list';
import {
createHttp,
createActionResultResponse,
createHttpMany,
createEntityResponse,
} from 'gmp/commands/testing';

Expand Down Expand Up @@ -95,14 +94,13 @@ describe('PortListCommand tests', () => {
action: 'delete_port_range',
id: '12345',
});
const entityResponse = createEntityResponse('port_list', {id: '324'});
const http = createHttpMany([response, entityResponse]);
const http = createHttp(response);
const command = new PortListCommand(http);
const result = await command.deletePortRange({
id: '12345',
portListId: '67890',
});
expect(result.data.id).toEqual('324');
expect(result).toBeUndefined();
expect(http.request).toHaveBeenCalledTimes(1);
});

test('should allow to get a port list', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ describe('WebApplicationTargetCommand tests', () => {
in_use: YES_VALUE,
},
});
expect(result.data.id).toEqual('wat-123');
expect(result).toBeUndefined();
});

test('should omit exclude_url when not provided in save', async () => {
Expand Down
6 changes: 5 additions & 1 deletion src/gmp/commands/credential-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ export interface CredentialStoreModifyParams {
serverCaCertificate?: File;
}

export interface CredentialStoreVerifyParams {
id: string;
}

const log = logger.getLogger('gmp.commands.credentialStore');

class CredentialStoreCommand extends EntityCommand<
Expand Down Expand Up @@ -90,7 +94,7 @@ class CredentialStoreCommand extends EntityCommand<
});
}

async verify({id}: {id: string}): Promise<EntityActionResponse> {
async verify({id}: CredentialStoreVerifyParams) {
log.debug('Verifying credential store', {id});

return this.entityAction({
Expand Down
6 changes: 3 additions & 3 deletions src/gmp/commands/credential.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ interface CredentialCommandSnmpFields {
}

// Create operation interfaces
type CredentialCommandCreateArgs = CredentialCommandBaseArgs;
export type CredentialCommandCreateParams = CredentialCommandBaseArgs;

interface CredentialCommandKrb5Args
extends CredentialCommandBaseArgs, CredentialCommandKrb5Fields {}
Expand Down Expand Up @@ -145,9 +145,9 @@ class CredentialCommand extends EntityCommand<
};
}

create(args: CredentialCommandCreateArgs) {
create(args: CredentialCommandCreateParams) {
const baseData = this.createBase(args);
return this.action(baseData);
return this.entityAction(baseData);
}

createKrb5(args: CredentialCommandKrb5Args) {
Expand Down
15 changes: 5 additions & 10 deletions src/gmp/commands/port-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,18 @@ export interface PortListCommandSaveParams {
comment?: string;
}

interface PortListCommandCreatePortRangeParams {
export interface PortListCommandCreatePortRangeParams {
portListId: string;
portRangeStart: number;
portRangeEnd: number;
portType: string;
}

interface PortListCommandDeletePortRangeParams {
export interface PortListCommandDeletePortRangeParams {
id: string;
portListId: string;
}

interface PortListCommandImportParams {
export interface PortListCommandImportParams {
xmlFile?: File;
}

Expand Down Expand Up @@ -101,16 +100,12 @@ class PortListCommand extends EntityCommand<PortList, PortListElement> {
});
}

async deletePortRange({
id,
portListId,
}: PortListCommandDeletePortRangeParams) {
await this.httpPostWithTransform({
async deletePortRange({id}: PortListCommandDeletePortRangeParams) {
await this.action({
cmd: 'delete_port_range',
port_range_id: id,
no_redirect: 1,
});
return await this.get({id: portListId});
}

import({xmlFile}: PortListCommandImportParams) {
Expand Down
2 changes: 1 addition & 1 deletion src/gmp/commands/target.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {UNSET_VALUE} from 'web/utils/Render';
export type TargetSource = 'manual' | 'file' | 'asset_hosts';
export type TargetExcludeSource = 'manual' | 'file';

interface TargetCommandCreateParams {
export interface TargetCommandCreateParams {
aliveTests?: AliveTest[];
allowSimultaneousIPs?: boolean;
comment?: string;
Expand Down
6 changes: 3 additions & 3 deletions src/gmp/commands/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,9 @@ interface SaveArguments extends CreateArguments {
oldName: string;
}

interface DeleteArguments {
export interface UserCommandDeleteParams {
id: string;
inheritorId: string;
inheritorId?: string;
}

const log = logger.getLogger('gmp.commands.users');
Expand Down Expand Up @@ -367,7 +367,7 @@ class UserCommand extends EntityCommand<User, PortListElement> {
return this.action(data);
}

async delete({id, inheritorId}: DeleteArguments) {
async delete({id, inheritorId}: UserCommandDeleteParams) {
const data = {
cmd: 'delete_user',
id,
Expand Down
4 changes: 2 additions & 2 deletions src/gmp/commands/web-application-target.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,15 +81,15 @@ class WebApplicationTargetCommand extends EntityCommand<WebApplicationTarget> {
reverseLookupOnly,
reverseLookupUnify,
inUse,
}: WebApplicationTargetSaveParams): Promise<EntityActionResponse> {
}: WebApplicationTargetSaveParams) {
log.debug('Modifying web application target', {
id,
name,
comment,
urls,
credentialId,
});
return this.entityAction({
await this.entityAction({
cmd: 'save_web_application_target',
web_application_target_id: id,
name,
Expand Down
21 changes: 12 additions & 9 deletions src/web/entity/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,23 @@ import {type EntityType} from 'gmp/utils/entity-type';
import {isDefined, isFunction} from 'gmp/utils/identity';
import {entityListURL, entityURL, type EntityListType} from 'web/route-paths';

export type NavigateFunc = (path: string) => void;
type NavigateFunc = (path: string) => void;

export interface NavigateObj {
interface NavigateObj {
navigate: NavigateFunc;
}

export type Navigate = NavigateFunc | NavigateObj;
type Navigate = NavigateFunc | NavigateObj;

export interface GotoDetailsObj {
data: {
id: string;
};
interface GotoDetailsData {
id: string;
}

export type GotoDetailsFunc = ({data}: GotoDetailsObj) => void;
interface GotoDetailsObj {
data: GotoDetailsData;
}

export type GotoDetailsFunc = (data: GotoDetailsObj | GotoDetailsData) => void;
export type GotoListFunc = () => void;

/**
Expand All @@ -47,7 +49,8 @@ export const goToDetails = (
throw new Error('navigate function is required for goToDetails');
}
}
return ({data}) => navigate(entityURL(type, String(data.id)));
return data =>
navigate(entityURL(type, String('id' in data ? data.id : data.data.id)));
};

/**
Expand Down
97 changes: 97 additions & 0 deletions src/web/hooks/use-query/__tests__/Agent.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/* SPDX-FileCopyrightText: 2026 Greenbone AG
*
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import {describe, expect, test, testing} from '@gsa/testing';
import {fireEvent, rendererWith, screen, waitFor} from 'web/testing';
import {createSession} from 'gmp/testing';
import {
useDeleteAgent,
useDownloadAgentSupportBundle,
useModifyAgent,
} from 'web/hooks/use-query/agent';

const createGmp = () => ({
session: createSession({token: 'test-token'}),
settings: {},
agent: {
save: testing.fn().mockResolvedValue(undefined),
delete: testing.fn().mockResolvedValue(undefined),
downloadSupportBundle: testing
.fn()
.mockResolvedValue({data: new ArrayBuffer(0)}),
},
});

describe('useModifyAgent', () => {
test('should save an agent', async () => {
const gmp = createGmp();
const {render} = rendererWith({gmp, router: true});
const input = {agentsIds: ['agent-1'], authorized: true};
const TestComponent = () => {
const mutation = useModifyAgent();
return <button onClick={() => mutation.mutate(input)}>Save</button>;
};

render(<TestComponent />);
fireEvent.click(screen.getByRole('button', {name: 'Save'}));
await waitFor(() => {
expect(gmp.agent.save.mock.calls[0][0]).toEqual(input);
});
});
});

describe('useDeleteAgent', () => {
test('should delete an agent', async () => {
const gmp = createGmp();
const {render} = rendererWith({gmp, router: true});
const TestComponent = () => {
const mutation = useDeleteAgent({});
return (
<button
onClick={() =>
mutation.mutate({
id: 'agent-1',
name: 'Deleted Agent',
})
}
>
Delete
</button>
);
};

render(<TestComponent />);
fireEvent.click(screen.getByRole('button', {name: 'Delete'}));
await waitFor(() => {
expect(gmp.agent.delete).toHaveBeenCalledWith({id: 'agent-1'});
});
});
});

describe('useDownloadAgentSupportBundle', () => {
test('should download an agent support bundle', async () => {
const gmp = createGmp();
const {render} = rendererWith({gmp, router: true});
const TestComponent = () => {
const mutation = useDownloadAgentSupportBundle();
return (
<button
onClick={() => mutation.mutate({id: 'agent-1', encryption: false})}
>
Download
</button>
);
};

render(<TestComponent />);
fireEvent.click(screen.getByRole('button', {name: 'Download'}));
await waitFor(() => {
expect(gmp.agent.downloadSupportBundle).toHaveBeenCalledWith(
'agent-1',
false,
);
});
});
});
Loading
Loading