Skip to content

Commit f591623

Browse files
committed
Add database token helpers
1 parent 212990c commit f591623

7 files changed

Lines changed: 169 additions & 43 deletions

File tree

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export type DatabaseToken = {
2+
id: number;
3+
name: string;
4+
workspace: number;
5+
key: string;
6+
permissions: {
7+
create: boolean;
8+
read: boolean;
9+
update: boolean;
10+
delete: boolean;
11+
};
12+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export * from './application';
22
export * from './auth-user';
3+
export * from './database-token';
34
export * from './mcp';
45
export * from './table-workspace';
56
export * from './user';

packages/server/api/src/app/openops-tables/create-database-token.ts

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,19 @@
1-
import { createAxiosHeaders, makeOpenOpsTablesPost } from '@openops/common';
1+
import {
2+
createAxiosHeaders,
3+
DatabaseToken,
4+
makeOpenOpsTablesPost,
5+
} from '@openops/common';
26

3-
const TOKEN_NAME_PREFIX = 'Project_';
4-
5-
export type DatabaseToken = {
6-
id: number;
7-
name: string;
8-
workspace: number;
9-
key: string;
10-
permissions: {
11-
create: boolean;
12-
read: boolean;
13-
update: boolean;
14-
delete: boolean;
15-
};
16-
};
17-
18-
export type CreateDatabaseTokenParams = {
19-
token: string;
20-
projectId: string;
21-
workspaceId: number;
22-
};
23-
24-
export async function createProjectDatabaseToken(
25-
params: CreateDatabaseTokenParams,
7+
export async function createDatabaseToken(
8+
workspaceId: number,
9+
token: string,
2610
): Promise<DatabaseToken> {
2711
const payload = {
28-
name: `${TOKEN_NAME_PREFIX}${params.projectId}`,
29-
workspace: params.workspaceId,
12+
name: 'OpenOps Token',
13+
workspace: workspaceId,
3014
};
3115

32-
const headers = createAxiosHeaders(params.token);
16+
const headers = createAxiosHeaders(token);
3317

3418
return makeOpenOpsTablesPost<DatabaseToken>(
3519
'api/database/tokens/',

packages/server/api/src/app/openops-tables/index.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import { addUserToWorkspace } from './add-user-workspace';
22
import { createDatabase } from './create-database';
3-
import { createProjectDatabaseToken } from './create-database-token';
3+
import { createDatabaseToken } from './create-database-token';
44
import { createMcpEndpoint } from './create-mcp-endpoint';
55
import { createTable } from './create-table';
66
import { createUser } from './create-user';
77
import { createWorkspace } from './create-workspace';
88
import { createDefaultWorkspaceAndDatabase } from './default-workspace-database';
99
import { getMcpEndpointList } from './get-mcp-endpoint-list';
1010
import { getWorkspaceByName } from './get-workspace-by-name';
11+
import { listDatabaseTokens } from './list-database-tokens';
1112
import { listDatabases } from './list-databases';
1213
import { listWorkspaces } from './list-workspaces';
1314
import { renameDatabase } from './rename-database';
@@ -17,7 +18,8 @@ export const openopsTables = {
1718
addUserToWorkspace,
1819
listDatabases,
1920
createDatabase,
20-
createProjectDatabaseToken,
21+
listDatabaseTokens,
22+
createDatabaseToken,
2123
createTable,
2224
listWorkspaces,
2325
createWorkspace,
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import {
2+
createAxiosHeaders,
3+
DatabaseToken,
4+
makeOpenOpsTablesGet,
5+
} from '@openops/common';
6+
7+
export async function listDatabaseTokens(
8+
workspaceId: number,
9+
token: string,
10+
): Promise<DatabaseToken[]> {
11+
const tokens = await makeOpenOpsTablesGet<DatabaseToken>(
12+
'api/database/tokens/',
13+
createAxiosHeaders(token),
14+
);
15+
16+
return tokens.flat().filter((t) => t.workspace === workspaceId);
17+
}

packages/server/api/test/unit/openops-tables/create-database-token.test.ts

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,20 @@ const openopsCommonMock = {
66
jest.mock('@openops/common', () => openopsCommonMock);
77

88
import { AxiosHeaders } from 'axios';
9-
import { createProjectDatabaseToken } from '../../../src/app/openops-tables/create-database-token';
9+
import { createDatabaseToken } from '../../../src/app/openops-tables/create-database-token';
1010

11-
describe('createProjectDatabaseToken', () => {
11+
describe('createDatabaseToken', () => {
1212
beforeEach(() => {
1313
jest.clearAllMocks();
1414
});
1515

1616
it('should return the created token on successful creation', async () => {
17-
const params = {
18-
token: 'test_system_token',
19-
projectId: 'test-project-123',
20-
workspaceId: 1,
21-
};
17+
const token = 'test_system_token';
18+
const workspaceId = 1;
19+
2220
const mockHeaders = new AxiosHeaders({
2321
'Content-Type': 'application/json',
24-
Authorization: `JWT ${params.token}`,
22+
Authorization: `JWT ${token}`,
2523
});
2624
const mockTokenResponse = {
2725
id: 1,
@@ -41,18 +39,16 @@ describe('createProjectDatabaseToken', () => {
4139
mockTokenResponse,
4240
);
4341

44-
const result = await createProjectDatabaseToken(params);
42+
const result = await createDatabaseToken(workspaceId, token);
4543

4644
expect(result).toEqual(mockTokenResponse);
4745
expect(openopsCommonMock.createAxiosHeaders).toHaveBeenCalledTimes(1);
48-
expect(openopsCommonMock.createAxiosHeaders).toHaveBeenCalledWith(
49-
params.token,
50-
);
46+
expect(openopsCommonMock.createAxiosHeaders).toHaveBeenCalledWith(token);
5147
expect(openopsCommonMock.makeOpenOpsTablesPost).toHaveBeenCalledWith(
5248
'api/database/tokens/',
5349
{
54-
name: 'Project_test-project-123',
55-
workspace: params.workspaceId,
50+
name: 'OpenOps Token',
51+
workspace: workspaceId,
5652
},
5753
mockHeaders,
5854
);
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
const openopsCommonMock = {
2+
...jest.requireActual('@openops/common'),
3+
makeOpenOpsTablesGet: jest.fn(),
4+
};
5+
jest.mock('@openops/common', () => openopsCommonMock);
6+
7+
import { DatabaseToken } from '@openops/common';
8+
import { AxiosHeaders } from 'axios';
9+
import { listDatabaseTokens } from '../../../src/app/openops-tables/list-database-tokens';
10+
11+
describe('listDatabases', () => {
12+
beforeEach(() => {
13+
jest.clearAllMocks();
14+
});
15+
16+
it('should return only database tokens for the provided workspace', async () => {
17+
const workspaceId = 1;
18+
const token = 'test_token';
19+
const mockApplications: DatabaseToken[] = [
20+
{
21+
id: 1,
22+
name: 'Token 1',
23+
workspace: workspaceId,
24+
key: 'key',
25+
permissions: { create: true, read: true, update: true, delete: true },
26+
},
27+
{
28+
id: 2,
29+
name: 'Token 2',
30+
workspace: 2,
31+
key: 'key',
32+
permissions: { create: true, read: true, update: true, delete: true },
33+
},
34+
{
35+
id: 3,
36+
name: 'Token 3',
37+
workspace: workspaceId,
38+
key: 'key',
39+
permissions: { create: true, read: true, update: true, delete: true },
40+
},
41+
{
42+
id: 4,
43+
name: 'Token 4',
44+
workspace: 2,
45+
key: 'key',
46+
permissions: { create: true, read: true, update: true, delete: true },
47+
},
48+
];
49+
50+
openopsCommonMock.makeOpenOpsTablesGet.mockResolvedValue([
51+
mockApplications,
52+
]);
53+
54+
const result = await listDatabaseTokens(workspaceId, token);
55+
56+
expect(result).toHaveLength(2);
57+
expect(result).toEqual([mockApplications[0], mockApplications[2]]);
58+
expect(openopsCommonMock.makeOpenOpsTablesGet).toHaveBeenCalledWith(
59+
'api/database/tokens/',
60+
new AxiosHeaders({
61+
'Content-Type': 'application/json',
62+
Authorization: `JWT ${token}`,
63+
}),
64+
);
65+
});
66+
67+
it('should return empty array when no database tokens exist for the workspace', async () => {
68+
const workspaceId = 1;
69+
const token = 'test_token';
70+
const mockApplications: DatabaseToken[] = [
71+
{
72+
id: 4,
73+
name: 'Token 4',
74+
workspace: 2,
75+
key: 'key',
76+
permissions: { create: true, read: true, update: true, delete: true },
77+
},
78+
];
79+
80+
openopsCommonMock.makeOpenOpsTablesGet.mockResolvedValue(mockApplications);
81+
82+
const result = await listDatabaseTokens(workspaceId, token);
83+
84+
expect(result).toHaveLength(0);
85+
expect(result).toEqual([]);
86+
expect(openopsCommonMock.makeOpenOpsTablesGet).toHaveBeenCalledWith(
87+
'api/database/tokens/',
88+
new AxiosHeaders({
89+
'Content-Type': 'application/json',
90+
Authorization: `JWT ${token}`,
91+
}),
92+
);
93+
});
94+
95+
it('should return empty array when no database tokens exist', async () => {
96+
const workspaceId = 1;
97+
const token = 'test_token';
98+
const mockApplications: DatabaseToken[] = [];
99+
100+
openopsCommonMock.makeOpenOpsTablesGet.mockResolvedValue(mockApplications);
101+
102+
const result = await listDatabaseTokens(workspaceId, token);
103+
104+
expect(result).toHaveLength(0);
105+
expect(result).toEqual([]);
106+
expect(openopsCommonMock.makeOpenOpsTablesGet).toHaveBeenCalledWith(
107+
'api/database/tokens/',
108+
new AxiosHeaders({
109+
'Content-Type': 'application/json',
110+
Authorization: `JWT ${token}`,
111+
}),
112+
);
113+
});
114+
});

0 commit comments

Comments
 (0)