Skip to content

Commit f892b1c

Browse files
committed
Enable project-scoped database tokens for tables service API calls in blocks
1 parent e3c6c1b commit f892b1c

22 files changed

Lines changed: 597 additions & 109 deletions

packages/blocks/openops-tables/src/actions/delete-record-action.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { BlockAuth, createAction, Property } from '@openops/blocks-framework';
22
import {
3-
authenticateDefaultUserInOpenOpsTables,
43
deleteRow,
54
getFields,
65
getPrimaryKeyFieldFromFields,
6+
getProjectDatabaseTokenForBlock,
77
getRowByPrimaryKeyValue,
88
getTableIdByTableName,
99
openopsTablesDropdownProperty,
@@ -27,15 +27,20 @@ export const deleteRecordAction = createAction({
2727
},
2828
async run(context) {
2929
const tableName = context.propsValue.tableName as unknown as string;
30-
const tableCacheKey = `${context.run.id}-table-${tableName}`;
30+
31+
const token = await getProjectDatabaseTokenForBlock(
32+
context.server.apiUrl,
33+
context.server.token,
34+
context.project.id,
35+
);
36+
37+
const tableCacheKey = `${context.run.id}-table-${tableName}-${token}`;
3138
const tableId = await cacheWrapper.getOrAdd(
3239
tableCacheKey,
3340
getTableIdByTableName,
34-
[tableName],
41+
[tableName, token, false],
3542
);
3643

37-
const { token } = await authenticateDefaultUserInOpenOpsTables();
38-
3944
const fieldsCacheKey = `${context.run.id}-${tableId}-fields`;
4045
const fields = await cacheWrapper.getOrAdd(fieldsCacheKey, getFields, [
4146
tableId,

packages/blocks/openops-tables/src/actions/get-records-action.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { BlockAuth, createAction, Property } from '@openops/blocks-framework';
22
import {
3-
authenticateDefaultUserInOpenOpsTables,
43
FilterType,
4+
getProjectDatabaseTokenForBlock,
55
getPropertyFromField,
66
getRows,
77
getTableFields,
@@ -41,14 +41,23 @@ export const getRecordsAction = createAction({
4141
displayName: '',
4242
required: true,
4343
refreshers: ['tableName'],
44-
props: async ({ tableName }) => {
44+
props: async ({ tableName }, ctx) => {
4545
if (!tableName) {
4646
return {};
4747
}
4848
const properties: { [key: string]: any } = {};
4949

50+
const token = await getProjectDatabaseTokenForBlock(
51+
ctx.server.apiUrl,
52+
ctx.server.token,
53+
ctx.project.id,
54+
);
55+
5056
const tableFields = await getTableFields(
5157
tableName as unknown as string,
58+
undefined,
59+
token,
60+
false,
5261
);
5362

5463
properties['filters'] = Property.Array({
@@ -113,15 +122,19 @@ export const getRecordsAction = createAction({
113122
}),
114123
},
115124
async run(context) {
116-
const { token } = await authenticateDefaultUserInOpenOpsTables();
125+
const token = await getProjectDatabaseTokenForBlock(
126+
context.server.apiUrl,
127+
context.server.token,
128+
context.project.id,
129+
);
117130

118131
const tableName = context.propsValue.tableName as unknown as string;
119132

120-
const tableCacheKey = `${context.run.id}-table-${tableName}`;
133+
const tableCacheKey = `${context.run.id}-table-${tableName}-${token}`;
121134
const tableId = await cacheWrapper.getOrAdd(
122135
tableCacheKey,
123136
getTableIdByTableName,
124-
[tableName],
137+
[tableName, token, false],
125138
);
126139

127140
const filtersProps = context.propsValue.filters['filters'] as unknown as {

packages/blocks/openops-tables/src/actions/get-table-url-action.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { BlockAuth, createAction } from '@openops/blocks-framework';
22
import {
3+
getProjectDatabaseTokenForBlock,
34
getTableIdByTableName,
45
openopsTablesDropdownProperty,
56
} from '@openops/common';
@@ -17,8 +18,14 @@ export const getTableUrlAction = createAction({
1718
tableName: openopsTablesDropdownProperty(),
1819
},
1920
async run(context) {
21+
const token = await getProjectDatabaseTokenForBlock(
22+
context.server.apiUrl,
23+
context.server.token,
24+
context.project.id,
25+
);
26+
2027
const tableName = context.propsValue.tableName as unknown as string;
21-
const tableId = await getTableIdByTableName(tableName);
28+
const tableId = await getTableIdByTableName(tableName, token, false);
2229
const baseUrl = system.getOrThrow(SharedSystemProp.FRONTEND_URL);
2330

2431
return (

packages/blocks/openops-tables/src/actions/update-record-action.ts

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { BlockAuth, createAction, Property } from '@openops/blocks-framework';
22
import {
3-
authenticateDefaultUserInOpenOpsTables,
43
getFields,
54
getPrimaryKeyFieldFromFields,
5+
getProjectDatabaseTokenForBlock,
66
getPropertyFromField,
77
getTableFields,
88
getTableIdByTableName,
@@ -29,12 +29,23 @@ export const updateRecordAction = createAction({
2929
'The primary key value of the row to update. If the row does not exist, a new row will be created.',
3030
required: true,
3131
refreshers: ['tableName'],
32-
props: async ({ tableName }) => {
32+
props: async ({ tableName }, ctx) => {
3333
if (!tableName) {
3434
return {};
3535
}
3636

37-
const fields = await getTableFields(tableName as unknown as string);
37+
const token = await getProjectDatabaseTokenForBlock(
38+
ctx.server.apiUrl,
39+
ctx.server.token,
40+
ctx.project.id,
41+
);
42+
43+
const fields = await getTableFields(
44+
tableName as unknown as string,
45+
undefined,
46+
token,
47+
false,
48+
);
3849

3950
const primaryKeyField = getPrimaryKeyFieldFromFields(fields);
4051

@@ -61,13 +72,22 @@ export const updateRecordAction = createAction({
6172
description: '',
6273
required: true,
6374
refreshers: ['tableName'],
64-
props: async ({ tableName }) => {
75+
props: async ({ tableName }, ctx) => {
6576
if (!tableName) {
6677
return {};
6778
}
6879

80+
const token = await getProjectDatabaseTokenForBlock(
81+
ctx.server.apiUrl,
82+
ctx.server.token,
83+
ctx.project.id,
84+
);
85+
6986
const tableFields = await getTableFields(
7087
tableName as unknown as string,
88+
undefined,
89+
token,
90+
false,
7191
);
7292

7393
const properties: { [key: string]: any } = {};
@@ -124,15 +144,19 @@ export const updateRecordAction = createAction({
124144
const roundToFieldPrecision =
125145
(context.propsValue.roundToFieldPrecision as boolean) ?? false;
126146

127-
const tableCacheKey = `${context.run.id}-table-${tableName}`;
147+
const token = await getProjectDatabaseTokenForBlock(
148+
context.server.apiUrl,
149+
context.server.token,
150+
context.project.id,
151+
);
152+
153+
const tableCacheKey = `${context.run.id}-table-${tableName}-${token}`;
128154
const tableId = await cacheWrapper.getOrAdd(
129155
tableCacheKey,
130156
getTableIdByTableName,
131-
[tableName],
157+
[tableName, token, false],
132158
);
133159

134-
const { token } = await authenticateDefaultUserInOpenOpsTables();
135-
136160
const fieldsCacheKey = `${context.run.id}-${tableId}-fields`;
137161
const tableFields = await cacheWrapper.getOrAdd(fieldsCacheKey, getFields, [
138162
tableId,

packages/blocks/openops-tables/test/actions/delete-record-action.test.ts

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jest.mock('@openops/server-shared', () => ({
99
}));
1010

1111
const openopsCommonMock = {
12-
authenticateDefaultUserInOpenOpsTables: jest.fn(),
12+
getProjectDatabaseTokenForBlock: jest.fn(),
1313
getRowByPrimaryKeyValue: jest.fn(),
1414
getPrimaryKeyFieldFromFields: jest.fn(),
1515
openopsTablesDropdownProperty: jest.fn().mockReturnValue({
@@ -21,10 +21,10 @@ const openopsCommonMock = {
2121
};
2222

2323
jest.mock('@openops/common', () => openopsCommonMock);
24-
import { nanoid } from 'nanoid';
2524
import { deleteRecordAction } from '../../src/actions/delete-record-action';
2625

2726
import { getFields, getTableIdByTableName } from '@openops/common';
27+
import { createBaseContext } from './test-helpers';
2828

2929
describe('deleteRecordAction', () => {
3030
beforeEach(() => {
@@ -45,14 +45,14 @@ describe('deleteRecordAction', () => {
4545
});
4646
});
4747

48-
test('should authenticate', async () => {
48+
test('should get project database token', async () => {
4949
openopsCommonMock.getPrimaryKeyFieldFromFields.mockReturnValue({
5050
name: 'primary key field',
5151
});
5252
openopsCommonMock.getRowByPrimaryKeyValue.mockResolvedValue([{ id: 1 }]);
53-
openopsCommonMock.authenticateDefaultUserInOpenOpsTables.mockResolvedValue({
54-
token: 'some databaseToken',
55-
});
53+
openopsCommonMock.getProjectDatabaseTokenForBlock.mockResolvedValue(
54+
'some databaseToken',
55+
);
5656
cacheWrapperMock.getOrAdd
5757
.mockReturnValueOnce(1)
5858
.mockReturnValue('mock result');
@@ -66,11 +66,15 @@ describe('deleteRecordAction', () => {
6666

6767
expect(result).toStrictEqual('mock result');
6868
expect(
69-
openopsCommonMock.authenticateDefaultUserInOpenOpsTables,
69+
openopsCommonMock.getProjectDatabaseTokenForBlock,
7070
).toHaveBeenCalledTimes(1);
7171
expect(
72-
openopsCommonMock.authenticateDefaultUserInOpenOpsTables,
73-
).toHaveBeenCalledWith();
72+
openopsCommonMock.getProjectDatabaseTokenForBlock,
73+
).toHaveBeenCalledWith(
74+
context.server.apiUrl,
75+
context.server.token,
76+
context.project.id,
77+
);
7478
});
7579

7680
test.each([[[]], [{}]])(
@@ -82,8 +86,8 @@ describe('deleteRecordAction', () => {
8286
cacheWrapperMock.getOrAdd
8387
.mockReturnValueOnce(1)
8488
.mockReturnValue(['some field']);
85-
openopsCommonMock.authenticateDefaultUserInOpenOpsTables.mockResolvedValue(
86-
{ token: 'some databaseToken' },
89+
openopsCommonMock.getProjectDatabaseTokenForBlock.mockResolvedValue(
90+
'some databaseToken',
8791
);
8892
const context = createContext({
8993
tableName: 'Opportunity',
@@ -115,8 +119,8 @@ describe('deleteRecordAction', () => {
115119
cacheWrapperMock.getOrAdd
116120
.mockReturnValueOnce(1)
117121
.mockReturnValue(['some field']);
118-
openopsCommonMock.authenticateDefaultUserInOpenOpsTables.mockResolvedValue(
119-
{ token: 'some databaseToken' },
122+
openopsCommonMock.getProjectDatabaseTokenForBlock.mockResolvedValue(
123+
'some databaseToken',
120124
);
121125
const context = createContext({
122126
tableName: 'Opportunity',
@@ -148,9 +152,9 @@ describe('deleteRecordAction', () => {
148152
.mockReturnValueOnce(1)
149153
.mockReturnValue(['some field']);
150154
openopsCommonMock.getRowByPrimaryKeyValue.mockResolvedValue(undefined);
151-
openopsCommonMock.authenticateDefaultUserInOpenOpsTables.mockResolvedValue({
152-
token: 'some databaseToken',
153-
});
155+
openopsCommonMock.getProjectDatabaseTokenForBlock.mockResolvedValue(
156+
'some databaseToken',
157+
);
154158
const context = createContext({
155159
tableName: 'Opportunity',
156160
rowPrimaryKey: 'some primary key value',
@@ -188,13 +192,13 @@ describe('deleteRecordAction', () => {
188192
.mockReturnValue(['some field']);
189193
openopsCommonMock.getRowByPrimaryKeyValue.mockResolvedValue({ id: 1 });
190194
openopsCommonMock.deleteRow.mockResolvedValue('mock result');
195+
openopsCommonMock.getProjectDatabaseTokenForBlock.mockResolvedValue(
196+
'some databaseToken',
197+
);
191198
const context = createContext({
192199
tableName: 'Opportunity',
193200
rowPrimaryKey: 'some primary key value',
194201
});
195-
openopsCommonMock.authenticateDefaultUserInOpenOpsTables.mockResolvedValue({
196-
token: 'some databaseToken',
197-
});
198202

199203
const result = (await deleteRecordAction.run(context)) as any;
200204

@@ -247,14 +251,10 @@ interface ContextParams {
247251
}
248252

249253
function createContext(params?: ContextParams) {
250-
return {
251-
...jest.requireActual('@openops/blocks-framework'),
254+
return createBaseContext({
252255
propsValue: {
253256
tableName: params?.tableName ?? '1',
254257
rowPrimaryKey: params?.rowPrimaryKey ?? 'default primary key',
255258
},
256-
run: {
257-
id: nanoid(),
258-
},
259-
};
259+
});
260260
}

0 commit comments

Comments
 (0)