Skip to content

Commit 647f70a

Browse files
committed
2 parents b10c366 + 084412f commit 647f70a

10 files changed

Lines changed: 166 additions & 17 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/authentication/basic/authentication-service.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export const authenticationService = {
5858
projectId: projectContext.project.id,
5959
projectRole: projectContext.projectRole,
6060
tablesRefreshToken: projectContext.tablesRefreshToken,
61+
tablesWorkspaceId: projectContext.project.tablesWorkspaceId,
6162
};
6263
},
6364
};

packages/server/api/src/app/authentication/context/authentication-cookies.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@ export function setAuthCookiesAndReply(
3030
expires: cookieExpiryDate,
3131
sameSite: 'lax',
3232
})
33+
.setCookie('baserow_group_id', String(response.tablesWorkspaceId), {
34+
domain: getOpenOpsSubDomain(),
35+
path: '/',
36+
signed: true,
37+
httpOnly: false,
38+
expires: cookieExpiryDate,
39+
sameSite: 'lax',
40+
})
3341
.send(response);
3442
}
3543

@@ -42,6 +50,10 @@ export function removeAuthCookiesAndReply(reply: FastifyReply): FastifyReply {
4250
.clearCookie('token', {
4351
path: '/',
4452
})
53+
.clearCookie('baserow_group_id', {
54+
domain: getOpenOpsSubDomain(),
55+
path: '/',
56+
})
4557
.send('Cookies removed');
4658
}
4759

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

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,8 @@
1-
import { createAxiosHeaders, makeOpenOpsTablesPost } from '@openops/common';
2-
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-
};
1+
import {
2+
createAxiosHeaders,
3+
DatabaseToken,
4+
makeOpenOpsTablesPost,
5+
} from '@openops/common';
176

187
export async function createDatabaseToken(
198
workspaceId: number,

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ 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,6 +18,7 @@ export const openopsTables = {
1718
addUserToWorkspace,
1819
listDatabases,
1920
createDatabase,
21+
listDatabaseTokens,
2022
createDatabaseToken,
2123
createTable,
2224
listWorkspaces,
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: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ jest.mock('@openops/common', () => openopsCommonMock);
88
import { AxiosHeaders } from 'axios';
99
import { createDatabaseToken } from '../../../src/app/openops-tables/create-database-token';
1010

11-
describe('createProjectDatabaseToken', () => {
11+
describe('createDatabaseToken', () => {
1212
beforeEach(() => {
1313
jest.clearAllMocks();
1414
});
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+
});

packages/shared/src/lib/authentication/dto/authentication-response.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ export type AuthenticationResponse = UserWithoutPassword & {
88
projectId: string;
99
projectRole: ProjectMemberRole | null;
1010
tablesRefreshToken: string;
11+
tablesWorkspaceId: number;
1112
};

0 commit comments

Comments
 (0)