- 
                Notifications
    You must be signed in to change notification settings 
- Fork 11
fix: remove unused api key calls #1628
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| Caution Review failedThe pull request is closed. WalkthroughRenamed and removed the findByIdWithSecret API across services and tests, consolidating lookups to the async findById. Updated auth role add/remove flows to operate directly on the returned ApiKey, initializing roles when absent, saving via saveApiKey, and enhancing error handling. Adjusted tests to initialize module state and cover error paths. Changes
 Sequence Diagram(s)sequenceDiagram
  autonumber
  participant C as Client
  participant Auth as AuthService
  participant KeySvc as ApiKeyService
  participant AuthZ as AuthzService
  participant Store as Storage
  rect rgb(240,248,255)
  note over C,Auth: Add role to API key (updated async flow)
  C->>Auth: addRoleToApiKey(apiKeyId, role)
  Auth->>KeySvc: findById(apiKeyId)
  KeySvc->>Store: read api-keys
  Store-->>KeySvc: ApiKey | null
  KeySvc-->>Auth: ApiKey | null
  alt ApiKey found
    Auth->>Auth: ensure roles[], mutate roles
    Auth->>KeySvc: saveApiKey(ApiKey)
    KeySvc->>Store: write api-key
    Store-->>KeySvc: ok
    KeySvc-->>Auth: ok
    Auth->>AuthZ: addRoleForUser(apiKeyId, role)
    AuthZ-->>Auth: ok
    Auth-->>C: result
  else Not found
    Auth-->>C: error "API key not found"
  end
  end
sequenceDiagram
  autonumber
  participant C as Client
  participant Auth as AuthService
  participant KeySvc as ApiKeyService
  participant AuthZ as AuthzService
  participant Store as Storage
  rect rgb(245,240,255)
  note over C,Auth: Remove role from API key (updated async flow)
  C->>Auth: removeRoleFromApiKey(apiKeyId, role)
  Auth->>KeySvc: findById(apiKeyId)
  KeySvc->>Store: read api-keys
  Store-->>KeySvc: ApiKey | null
  KeySvc-->>Auth: ApiKey | null
  alt ApiKey found
    Auth->>Auth: ensure roles[], filter role
    Auth->>KeySvc: saveApiKey(ApiKey)
    KeySvc->>Store: write api-key
    Store-->>KeySvc: ok
    KeySvc-->>Auth: ok
    Auth->>AuthZ: deleteRoleForUser(apiKeyId, role)
    AuthZ-->>Auth: ok
    Auth-->>C: result
  else Not found
    Auth-->>C: error "API key not found"
  end
  end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
 Poem
 📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 💡 Knowledge Base configuration: 
 You can enable these sources in your CodeRabbit configuration. 📒 Files selected for processing (5)
 ✨ Finishing Touches
 🧪 Generate unit tests
 🪧 TipsChatThere are 3 ways to chat with CodeRabbit: 
 SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type  Other keywords and placeholders
 CodeRabbit Configuration File ( | 
| Claude finished @elibosley's task —— View job PR Review - Critical Issues FoundTask: Review ONLY the diff/changeset for HIGH-PRIORITY issues Todo List: 
 🚨 Critical Issue Found in auth.service.tsCRITICAL BUG - Unnecessary I/O Operations in  In  if (!apiKey.roles) {
    apiKey.roles = [];  // Initialize empty array
}
apiKey.roles = apiKey.roles.filter((r) => r !== role);  // Filter (no-op if role not present)
await this.apiKeyService.saveApiKey(apiKey);            // ⚠️ Always saves, even when no change
await this.authzService.deleteRoleForUser(apiKeyId, role); // ⚠️ Always deletes, even if role wasn't thereProblems: 
 Recommended Fix: Check if role exists before filtering, only save/delete if changes were made. 🚨 Breaking Change IdentifiedPUBLIC API METHOD REMOVAL 
 ✅ Positive Changes Noted
 | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (3)
api/src/unraid-api/auth/auth.service.spec.ts (1)
233-237: Make saveApiKey expectations less brittleUse partial/arrayContaining to reduce coupling to object shape and order.
Apply:
- expect(apiKeyService.saveApiKey).toHaveBeenCalledWith({ - ...mockApiKeyWithoutRole, - roles: [Role.ADMIN, role], - }); + expect(apiKeyService.saveApiKey).toHaveBeenCalledWith( + expect.objectContaining({ + id: apiKeyId, + roles: expect.arrayContaining([Role.ADMIN, role]), + }) + );- expect(apiKeyService.saveApiKey).toHaveBeenCalledWith({ - ...apiKey, - roles: [Role.GUEST], - }); + expect(apiKeyService.saveApiKey).toHaveBeenCalledWith( + expect.objectContaining({ + id: apiKey.id, + roles: [Role.GUEST], + }) + );Also applies to: 261-265
api/src/unraid-api/auth/api-key.service.spec.ts (2)
229-260: Duplicate “describe('findById')” blockThere are two describe('findById') sections; consolidate to avoid redundancy and future drift.
I can propose a follow-up patch to merge these tests into the first block and keep only unique scenarios (invalid structure/read error).
253-254: Follow testing guideline: avoid asserting exact error messagesPrefer generic
.rejects.toThrow()to reduce brittleness.Apply:
- await expect(apiKeyService.onModuleInit()).rejects.toThrow('Invalid API key structure'); + await expect(apiKeyService.onModuleInit()).rejects.toThrow();- await expect(apiKeyService.onModuleInit()).rejects.toThrow('Read failed'); + await expect(apiKeyService.onModuleInit()).rejects.toThrow();Also applies to: 258-259
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (6)
- api/src/unraid-api/auth/api-key.service.spec.ts(4 hunks)
- api/src/unraid-api/auth/api-key.service.ts(1 hunks)
- api/src/unraid-api/auth/auth.service.spec.ts(2 hunks)
- api/src/unraid-api/auth/auth.service.ts(2 hunks)
- packages/unraid-api-plugin-connect/src/authn/connect-api-key.service.ts(0 hunks)
- packages/unraid-shared/src/services/api-key.ts(0 hunks)
💤 Files with no reviewable changes (2)
- packages/unraid-shared/src/services/api-key.ts
- packages/unraid-api-plugin-connect/src/authn/connect-api-key.service.ts
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
TypeScript source files must use import specifiers with .js extensions for ESM compatibility
Files:
- api/src/unraid-api/auth/auth.service.ts
- api/src/unraid-api/auth/api-key.service.ts
- api/src/unraid-api/auth/auth.service.spec.ts
- api/src/unraid-api/auth/api-key.service.spec.ts
api/src/unraid-api/**
📄 CodeRabbit inference engine (CLAUDE.md)
Place new API source files in api/src/unraid-api/ rather than legacy locations
Prefer adding new files to the Nest repo at api/src/unraid-api/ instead of legacy code
Files:
- api/src/unraid-api/auth/auth.service.ts
- api/src/unraid-api/auth/api-key.service.ts
- api/src/unraid-api/auth/auth.service.spec.ts
- api/src/unraid-api/auth/api-key.service.spec.ts
**/*.{ts,tsx,js,jsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Avoid unnecessary or obvious comments; only add comments when needed for clarity
Files:
- api/src/unraid-api/auth/auth.service.ts
- api/src/unraid-api/auth/api-key.service.ts
- api/src/unraid-api/auth/auth.service.spec.ts
- api/src/unraid-api/auth/api-key.service.spec.ts
api/**/*.{test,spec}.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Prefer not to mock simple dependencies in API tests
Files:
- api/src/unraid-api/auth/auth.service.spec.ts
- api/src/unraid-api/auth/api-key.service.spec.ts
**/*.{test,spec}.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{test,spec}.{js,ts,jsx,tsx}: General testing: use .rejects.toThrow() without arguments when asserting thrown errors
General testing: focus on behavior, not exact error message wording
General testing: avoid brittle tests tied to non-essential details (exact messages, log formats)
General testing: use mocks as nouns (objects), not verbs (behavioral overuse)
Files:
- api/src/unraid-api/auth/auth.service.spec.ts
- api/src/unraid-api/auth/api-key.service.spec.ts
api/**/*.{test,spec}.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/api-rules.mdc)
api/**/*.{test,spec}.{js,jsx,ts,tsx}: Use Vitest for tests in the api; do not use Jest
Prefer not to mock simple dependencies in tests
For error testing, use.rejects.toThrow()without arguments; avoid asserting exact error messages unless the message format is the subject under test
Files:
- api/src/unraid-api/auth/auth.service.spec.ts
- api/src/unraid-api/auth/api-key.service.spec.ts
🧠 Learnings (8)
📓 Common learnings
Learnt from: mdatelle
PR: unraid/api#942
File: api/src/unraid-api/auth/auth.service.ts:0-0
Timestamp: 2024-11-04T20:44:46.432Z
Learning: When modifying `apiKey.roles` in `removeRoleFromApiKey` and `addRoleToApiKey` within `api/src/unraid-api/auth/auth.service.ts`, concurrency issues are not a concern because the keys are stored in the file system.
Learnt from: mdatelle
PR: unraid/api#942
File: api/src/unraid-api/auth/auth.service.ts:0-0
Timestamp: 2024-11-04T20:41:22.303Z
Learning: In `api/src/unraid-api/auth/auth.service.ts`, the `addRoleToApiKey` function operates on API keys stored as JSON files in a directory, not a database, so concurrency is not a concern for modifying `apiKey.roles`.
📚 Learning: 2024-11-04T20:44:46.432Z
Learnt from: mdatelle
PR: unraid/api#942
File: api/src/unraid-api/auth/auth.service.ts:0-0
Timestamp: 2024-11-04T20:44:46.432Z
Learning: When modifying `apiKey.roles` in `removeRoleFromApiKey` and `addRoleToApiKey` within `api/src/unraid-api/auth/auth.service.ts`, concurrency issues are not a concern because the keys are stored in the file system.
Applied to files:
- api/src/unraid-api/auth/auth.service.ts
- api/src/unraid-api/auth/api-key.service.ts
- api/src/unraid-api/auth/auth.service.spec.ts
- api/src/unraid-api/auth/api-key.service.spec.ts
📚 Learning: 2024-11-04T20:41:22.303Z
Learnt from: mdatelle
PR: unraid/api#942
File: api/src/unraid-api/auth/auth.service.ts:0-0
Timestamp: 2024-11-04T20:41:22.303Z
Learning: In `api/src/unraid-api/auth/auth.service.ts`, the `addRoleToApiKey` function operates on API keys stored as JSON files in a directory, not a database, so concurrency is not a concern for modifying `apiKey.roles`.
Applied to files:
- api/src/unraid-api/auth/auth.service.ts
- api/src/unraid-api/auth/api-key.service.ts
- api/src/unraid-api/auth/auth.service.spec.ts
- api/src/unraid-api/auth/api-key.service.spec.ts
📚 Learning: 2024-11-06T20:59:25.809Z
Learnt from: mdatelle
PR: unraid/api#942
File: api/src/unraid-api/graph/resolvers/auth/auth.resolver.ts:111-113
Timestamp: 2024-11-06T20:59:25.809Z
Learning: In the Unraid API project, error handling for mutations is handled at the service level rather than in the GraphQL resolvers. Specifically, in `api/src/unraid-api/graph/resolvers/auth/auth.resolver.ts`, methods like `removeRoleFromApiKey` rely on service-level error handling.
Applied to files:
- api/src/unraid-api/auth/auth.service.ts
- api/src/unraid-api/auth/auth.service.spec.ts
📚 Learning: 2024-11-15T16:22:03.485Z
Learnt from: elibosley
PR: unraid/api#942
File: api/src/unraid-api/auth/api-key.service.ts:176-188
Timestamp: 2024-11-15T16:22:03.485Z
Learning: Atomic writes are not required for the `saveApiKey` method in `ApiKeyService` (`api/src/unraid-api/auth/api-key.service.ts`) unless specifically needed.
Applied to files:
- api/src/unraid-api/auth/auth.service.ts
- api/src/unraid-api/auth/api-key.service.ts
- api/src/unraid-api/auth/auth.service.spec.ts
- api/src/unraid-api/auth/api-key.service.spec.ts
📚 Learning: 2024-11-06T20:59:06.096Z
Learnt from: mdatelle
PR: unraid/api#942
File: api/src/unraid-api/graph/resolvers/auth/auth.resolver.ts:87-89
Timestamp: 2024-11-06T20:59:06.096Z
Learning: Error handling in mutations like `addRoleForUser` in `auth.resolver.ts` is performed at the service level, so additional error handling in the resolver is unnecessary.
Applied to files:
- api/src/unraid-api/auth/auth.service.ts
📚 Learning: 2024-11-05T14:49:07.308Z
Learnt from: elibosley
PR: unraid/api#942
File: api/src/unraid-api/auth/api-key.service.ts:62-70
Timestamp: 2024-11-05T14:49:07.308Z
Learning: In `api/src/unraid-api/auth/api-key.service.ts`, when handling read errors in the `findById` method, throw a `GraphQLError` instead of an `InternalServerErrorException`.
Applied to files:
- api/src/unraid-api/auth/auth.service.ts
- api/src/unraid-api/auth/api-key.service.ts
- api/src/unraid-api/auth/api-key.service.spec.ts
📚 Learning: 2025-08-11T15:06:30.877Z
Learnt from: CR
PR: unraid/api#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-11T15:06:30.877Z
Learning: Applies to api/**/*.{test,spec}.{ts,tsx,js,jsx} : Prefer not to mock simple dependencies in API tests
Applied to files:
- api/src/unraid-api/auth/auth.service.spec.ts
- api/src/unraid-api/auth/api-key.service.spec.ts
🧬 Code graph analysis (3)
api/src/unraid-api/auth/auth.service.ts (1)
api/src/unraid-api/graph/resolvers/api-key/api-key.resolver.ts (1)
apiKey(28-33)
api/src/unraid-api/auth/api-key.service.ts (1)
api/src/unraid-api/graph/resolvers/api-key/api-key.resolver.ts (1)
apiKey(28-33)
api/src/unraid-api/auth/auth.service.spec.ts (1)
api/src/unraid-api/graph/resolvers/api-key/api-key.resolver.ts (1)
apiKey(28-33)
🔇 Additional comments (3)
api/src/unraid-api/auth/api-key.service.ts (2)
329-352: LGTM: update() now uses async findByIdSwitching to await findById aligns with the removal of findByIdWithSecret and keeps behavior consistent.
329-352: No remainingfindByIdWithSecretreferences found
- Ran ripgrep searches for both exact (
findByIdWithSecret) and partial (findByIdWith…) matches across the repository (excludingnode_modules) with zero hits.All clear—no stragglers remain.
api/src/unraid-api/auth/api-key.service.spec.ts (1)
356-378: LGTM: tests await onModuleInit and seed memoryApiKeysThis fixes potential flakiness around service initialization.
41ea19f    to
    f7f75e9      
    Compare
  
    Added checks to initialize the roles array for API keys if it is undefined, preventing potential errors when adding or removing roles. This change enhances the robustness of the role management functionality in the AuthService.
| This plugin has been deployed to Cloudflare R2 and is available for testing.  | 
🤖 I have created a release *beep* *boop* --- ## [4.16.0](v4.15.1...v4.16.0) (2025-08-27) ### Features * add `parityCheckStatus` field to `array` query ([#1611](#1611)) ([c508366](c508366)) * generated UI API key management + OAuth-like API Key Flows ([#1609](#1609)) ([674323f](674323f)) ### Bug Fixes * **connect:** clear `wanport` upon disabling remote access ([#1624](#1624)) ([9df6a3f](9df6a3f)) * **connect:** valid LAN FQDN while remote access is enabled ([#1625](#1625)) ([aa58888](aa58888)) * correctly parse periods in share names from ini file ([#1629](#1629)) ([7d67a40](7d67a40)) * **rc.unraid-api:** remove profile sourcing ([#1622](#1622)) ([6947b5d](6947b5d)) * remove unused api key calls ([#1628](#1628)) ([9cd0d6a](9cd0d6a)) * retry VMs init for up to 2 min ([#1612](#1612)) ([b2e7801](b2e7801)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Summary by CodeRabbit
New Features
Refactor
Bug Fixes
Tests
Chores