Skip to content

Commit ff7dd48

Browse files
ThisIsDemetriodemetrio.marino
andauthored
fix(view_audit_logs): params "from" and "to" now accept regular dates (#27)
* fix(view_audit_logs): params "from" and "to" now accept regular dates * fix: timezone in tests --------- Co-authored-by: demetrio.marino <[email protected]>
1 parent 6602d1e commit ff7dd48

File tree

5 files changed

+138
-11
lines changed

5 files changed

+138
-11
lines changed

src/apis/iamClient.test.ts

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import { IAMClient, IAMClientInternal, internalEndpoint } from './iamClient'
2121

2222
const tenantId = 'test-tenant-id'
2323

24+
process.env.TZ = 'UTC'
25+
2426
suite('IAM Internal Client', () => {
2527
const client = IAMClientInternal('', '')
2628
let agent: MockAgent
@@ -74,12 +76,32 @@ suite('IAM Internal Client', () => {
7476
query: {
7577
per_page: '200',
7678
page: '0',
77-
from: '0000000000000000',
78-
to: '9999999999999999',
79+
from: '1710154800000',
80+
to: '1710156600000',
81+
},
82+
}).reply(200, mockedResult)
83+
84+
const result = await client.companyAuditLogs(tenantId, '1710154800000', '1710156600000')
85+
t.assert.deepStrictEqual(result, mockedResult)
86+
})
87+
88+
test('list company audit logs with dates as a filter', async (t: TestContext) => {
89+
const mockedResult = [
90+
{ id: 'identity1', type: 'user', name: 'User 1' },
91+
]
92+
93+
agent.get(internalEndpoint).intercept({
94+
path: `/tenants/${tenantId}/audit-logs`,
95+
method: 'GET',
96+
query: {
97+
per_page: '200',
98+
page: '0',
99+
from: '1710154800000',
100+
to: '1710156600000',
79101
},
80102
}).reply(200, mockedResult)
81103

82-
const result = await client.companyAuditLogs(tenantId, '0000000000000000', '9999999999999999')
104+
const result = await client.companyAuditLogs(tenantId, '2024-03-11T11:00:00', '2024-03-11T11:30:00')
83105
t.assert.deepStrictEqual(result, mockedResult)
84106
})
85107

@@ -127,7 +149,27 @@ suite('IAM Client', () => {
127149
t.assert.deepStrictEqual(result, mockedResult)
128150
})
129151

130-
test('list company audit logs', async (t: TestContext) => {
152+
test('list company audit logs with unix timestamps as a filter', async (t: TestContext) => {
153+
const mockedResult = [
154+
{ id: 'identity1', type: 'user', name: 'User 1' },
155+
]
156+
157+
agent.get(mockedEndpoint).intercept({
158+
path: `/api/tenants/${tenantId}/audit-logs`,
159+
method: 'GET',
160+
query: {
161+
per_page: '200',
162+
page: '0',
163+
from: '1710154800000',
164+
to: '1710156600000',
165+
},
166+
}).reply(200, mockedResult)
167+
168+
const result = await client.companyAuditLogs(tenantId, '1710154800000', '1710156600000')
169+
t.assert.deepStrictEqual(result, mockedResult)
170+
})
171+
172+
test('list company audit logs with dates as a filter', async (t: TestContext) => {
131173
const mockedResult = [
132174
{ id: 'identity1', type: 'user', name: 'User 1' },
133175
]
@@ -138,12 +180,12 @@ suite('IAM Client', () => {
138180
query: {
139181
per_page: '200',
140182
page: '0',
141-
from: '0000000000000000',
142-
to: '9999999999999999',
183+
from: '1710154800000',
184+
to: '1710156600000',
143185
},
144186
}).reply(200, mockedResult)
145187

146-
const result = await client.companyAuditLogs(tenantId, '0000000000000000', '9999999999999999')
188+
const result = await client.companyAuditLogs(tenantId, '2024-03-11T11:00:00', '2024-03-11T11:30:00')
147189
t.assert.deepStrictEqual(result, mockedResult)
148190
})
149191
})

src/apis/iamClient.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import { UndiciHeaders } from 'undici/types/dispatcher'
1717

18+
import { formatQueryParamToUnixTimestamp } from './utils'
1819
import { HTTPClient } from './http-client'
1920

2021
export const internalEndpoint = process.env.IAM_INTERNAL_ENDPOINT || 'http://internal.local:3000'
@@ -47,8 +48,8 @@ export class IAMClient {
4748

4849
companyAuditLogs (tenantID: string, from?: string, to?: string): Promise<Record<string, unknown>[]> {
4950
const params = new URLSearchParams({
50-
...from && { from },
51-
...to && { to },
51+
...from && { from: formatQueryParamToUnixTimestamp(from) },
52+
...to && { to: formatQueryParamToUnixTimestamp(to) },
5253
})
5354

5455
return this.#client.getPaginated<Record<string, unknown>>(this.#companyAuditLogsPath(tenantID), params, 0)

src/apis/utils.test.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright Mia srl
2+
// SPDX-License-Identifier: Apache-2.0
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
import { suite, test, TestContext } from 'node:test'
17+
18+
import { formatQueryParamToUnixTimestamp } from './utils'
19+
20+
suite('formatQueryParamToUnixTimestamp', () => {
21+
test('should return undefined for undefined input', (t: TestContext) => {
22+
t.assert.equal(formatQueryParamToUnixTimestamp(undefined), undefined)
23+
})
24+
25+
test('should throw error for invalid date format', (t: TestContext) => {
26+
t.assert.throws(
27+
() => formatQueryParamToUnixTimestamp('invalid-date'),
28+
{ message: 'Invalid date format: invalid-date' },
29+
)
30+
})
31+
32+
test('should handle different valid date formats', (t: TestContext) => {
33+
const testCases = [
34+
{ input: '2023-12-31', expected: '1703980800000' },
35+
{ input: '2023-06-15T12:30:00+02:00', expected: '1686825000000' },
36+
{ input: '2023-06-15T10:30:00Z', expected: '1686825000000' },
37+
{ input: '2023-06-15T10:30:00.000Z', expected: '1686825000000' },
38+
{ input: '2023-06-15T10:30:00.000+00:00', expected: '1686825000000' },
39+
]
40+
41+
for (const { input, expected } of testCases) {
42+
t.assert.equal(formatQueryParamToUnixTimestamp(input), expected, `Failed for input: ${input} (expected: ${expected})`)
43+
}
44+
})
45+
})

src/apis/utils.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright Mia srl
2+
// SPDX-License-Identifier: Apache-2.0
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
/**
17+
* Transform a date string into a Unix timestamp in milliseconds.
18+
* The result is parsed into a string to be used as a query parameter.
19+
*
20+
* @param param a date string in ISO 8601 format or YYYY-MM-DD format.
21+
* @returns the Unix timestamp in milliseconds as a string, or undefined if the input is undefined.
22+
*/
23+
export function formatQueryParamToUnixTimestamp (param: string | undefined): string | undefined {
24+
if (!param) {
25+
return undefined
26+
}
27+
28+
let date = new Date(Number(param))
29+
if (isNaN(date.getTime())) {
30+
date = new Date(param)
31+
}
32+
33+
if (isNaN(date.getTime())) {
34+
console.log({ param, date, time: date.getTime() })
35+
throw new Error(`Invalid date format: ${param}`)
36+
}
37+
38+
return date.getTime().toString()
39+
}

src/tools/descriptions.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ export const paramsDescriptions = {
111111
IAM_IDENTITY_TYPE: 'Filter the IAM entities by type',
112112

113113
// Audit Logs
114-
AUDIT_LOG_FROM: 'The start date of the audit logs to fetch, in unix timestamp format',
115-
AUDIT_LOG_TO: 'The end date of the audit logs to fetch, in unix timestamp format',
114+
AUDIT_LOG_FROM: 'The start date of the audit logs to fetch, in ISO 8601 format (YYYY-MM-DDTHH:mm:ss), e.g., "2024-01-15T10:30:00"',
115+
AUDIT_LOG_TO: 'The end date of the audit logs to fetch, in ISO 8601 format (YYYY-MM-DDTHH:mm:ss), e.g., "2024-01-15T23:59:59"',
116116

117117
// Marketplace
118118
MARKETPLACE_ITEM_ID: `The marketplace item to use to create the service. Can be found in the itemId field of the ${toolNames.LIST_MARKETPLACE} tool`,

0 commit comments

Comments
 (0)