Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
904a22d
feat(project): add rate limit settings to project update and type def…
Dobrunia Nov 3, 2025
56dcbe9
Bump version up to 1.2.7
github-actions[bot] Nov 3, 2025
80f54fc
feat(project): implement updateProjectRateLimits mutation for modifyi…
Dobrunia Nov 3, 2025
6be9831
feat(project): add removeProjectRateLimits mutation to clear project …
Dobrunia Nov 3, 2025
4ba798d
refactor(project): update rateLimitSettings handling to allow null fo…
Dobrunia Nov 3, 2025
f327588
fix
Dobrunia Nov 3, 2025
b53e191
fix
Dobrunia Nov 3, 2025
ee988fc
validation
Dobrunia Nov 3, 2025
11416d7
Bump version up to 1.2.8
github-actions[bot] Nov 3, 2025
9bad90a
Merge branch 'master' into feat/rate-limits-settings
Dobrunia Nov 3, 2025
eb8a4dc
fix(project): enhance rate limit settings validation and error handling
Dobrunia Nov 4, 2025
2b140b7
Merge branch 'feat/rate-limits-settings' of https://github.com/codex-…
Dobrunia Nov 4, 2025
a541641
fix(project): simplify rate limit settings validation check
Dobrunia Nov 4, 2025
c05c552
fix(project): update MAX_PERIOD to 1 month in seconds for rate limit …
Dobrunia Nov 4, 2025
485d6a8
Merge branch 'master' into feat/rate-limits-settings
Dobrunia Nov 4, 2025
36c7dd3
Bump version up to 1.2.9
github-actions[bot] Nov 4, 2025
82bdbc9
Merge branch 'master' into feat/rate-limits-settings
Dobrunia Nov 4, 2025
a18e037
Bump version up to 1.2.10
github-actions[bot] Nov 4, 2025
f6413ce
fix(project): clarify rate limit period validation and update MAX_PER…
Dobrunia Nov 4, 2025
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hawk.api",
"version": "1.2.7",
"version": "1.2.8",
"main": "index.ts",
"license": "BUSL-1.1",
"scripts": {
Expand Down
73 changes: 73 additions & 0 deletions src/resolvers/project.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,79 @@ module.exports = {
}
},

/**
* Update project rate limits settings
*
* @param {ResolverObj} _obj
* @param {string} id - project id
* @param {Object | null} rateLimitSettings - rate limit settings (null to remove)
* @param {UserInContext} user - current authorized user {@see ../index.js}
* @param {ContextFactories} factories - factories for working with models
*
* @returns {Project}
*/
async updateProjectRateLimits(_obj, { id, rateLimitSettings }, { user, factories }) {
const project = await factories.projectsFactory.findById(id);

if (!project) {
throw new ApolloError('There is no project with that id');
}

if (project.workspaceId.toString() === '6213b6a01e6281087467cc7a') {
throw new ApolloError('Unable to update demo project');
}

// Validate rate limit settings if provided
if (rateLimitSettings !== null && rateLimitSettings !== undefined) {
const { N, T } = rateLimitSettings;

// Validate that N and T exist
if (N === undefined || N === null || T === undefined || T === null) {
throw new UserInputError(
'Rate limit settings must contain both N (threshold) and T (period) fields.'
);
}

// Validate N (threshold) - must be positive integer > 0
if (typeof N !== 'number' || !Number.isInteger(N) || N <= 0) {
throw new UserInputError(
'Invalid rate limit threshold. Must be a positive integer greater than 0.'
);
}

// Validate T (period) - must be positive integer >= 60
if (typeof T !== 'number' || !Number.isInteger(T) || T < 60) {
throw new UserInputError(
'Invalid rate limit period. Must be a positive integer greater than or equal to 60 seconds.'
);
}

// Validate reasonable maximums (prevent extremely large values)
const MAX_THRESHOLD = 1000000000; // 1 billion
const MAX_PERIOD = 31536000; // 1 year in seconds

if (N > MAX_THRESHOLD) {
throw new UserInputError(
`Rate limit threshold cannot exceed ${MAX_THRESHOLD.toLocaleString()}.`
);
}

if (T > MAX_PERIOD) {
throw new UserInputError(
`Rate limit period cannot exceed ${MAX_PERIOD.toLocaleString()} seconds (1 year).`
);
}
}

try {
return project.updateProject({
rateLimitSettings: rateLimitSettings || null,
});
} catch (err) {
throw new ApolloError('Something went wrong');
}
},

/**
* Generates new project integration token by id
*
Expand Down
54 changes: 54 additions & 0 deletions src/typeDefs/project.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,35 @@
import { gql } from 'apollo-server-express';

export default gql`
"""
Rate limits configuration input
"""
input RateLimitSettingsInput {
"""
Rate limit threshold (N events)
"""
N: Int!

"""
Rate limit period in seconds (T seconds)
"""
T: Int!
}

"""
Rate limits configuration
"""
type RateLimitSettings {
"""
Rate limit threshold (N events)
"""
N: Int!

"""
Rate limit period in seconds (T seconds)
"""
T: Int!
}

"""
Possible events order
Expand Down Expand Up @@ -253,6 +282,11 @@ type Project {
Event grouping patterns
"""
eventGroupingPatterns: [ProjectEventGroupingPattern]

"""
Rate limits configuration
"""
rateLimitSettings: RateLimitSettings
}

extend type Query {
Expand Down Expand Up @@ -305,6 +339,26 @@ extend type Mutation {
Project image
"""
image: Upload @uploadImage

"""
Rate limits configuration
"""
rateLimitSettings: RateLimitSettingsInput
): Project! @requireAdmin

"""
Update project rate limits settings
"""
updateProjectRateLimits(
"""
What project to update
"""
id: ID!

"""
Rate limits configuration. Pass null to remove rate limits.
"""
rateLimitSettings: RateLimitSettingsInput
): Project! @requireAdmin

"""
Expand Down
Loading