@@ -12,6 +12,8 @@ import { ConnectConfigService } from './connect-config.service.js';
1212export class ConnectApiKeyService implements ApiKeyService {
1313 private readonly logger = new Logger ( ConnectApiKeyService . name ) ;
1414 private static readonly validRoles : Set < Role > = new Set ( Object . values ( Role ) ) ;
15+ private static readonly CONNECT_API_KEY_NAME = 'Connect' ;
16+ private static readonly CONNECT_API_KEY_DESCRIPTION = 'Internal API Key Used By Unraid Connect to access your server resources for the connect.myunraid.net dashboard' ;
1517
1618 constructor (
1719 @Inject ( API_KEY_SERVICE_TOKEN )
@@ -72,11 +74,13 @@ export class ConnectApiKeyService implements ApiKeyService {
7274 public async createLocalConnectApiKey ( ) : Promise < ApiKeyWithSecret | null > {
7375 try {
7476 return await this . create ( {
75- name : 'Connect' ,
77+ name : ConnectApiKeyService . CONNECT_API_KEY_NAME ,
7678 description : 'API key for Connect user' ,
7779 roles : [ Role . CONNECT ] ,
7880 overwrite : true ,
7981 } ) ;
82+
83+ // Delete all other API keys with the role CONNECT
8084 } catch ( err ) {
8185 this . logger . error ( `Failed to create local API key for Connect user: ${ err } ` ) ;
8286 return null ;
@@ -87,21 +91,57 @@ export class ConnectApiKeyService implements ApiKeyService {
8791 * Gets or creates a local API key for Connect
8892 */
8993 public async getOrCreateLocalApiKey ( ) : Promise < string > {
90- // 1. Check in-memory config
94+ const targetDescription = ConnectApiKeyService . CONNECT_API_KEY_DESCRIPTION ;
95+
96+ // 1. Get all API keys first
97+ const allKeys = await this . findAll ( ) ;
98+
99+ // 2. Check in-memory config and verify key exists
91100 const { localApiKey : localApiKeyFromConfig } = this . connectConfig . getConfig ( ) ;
92101 if ( localApiKeyFromConfig && localApiKeyFromConfig !== '' ) {
93- return localApiKeyFromConfig ;
102+ const keyExists = allKeys . some ( key => {
103+ const keyWithSecret = this . findByIdWithSecret ( key . id ) ;
104+ return keyWithSecret ?. key === localApiKeyFromConfig ;
105+ } ) ;
106+ if ( keyExists ) {
107+ return localApiKeyFromConfig ;
108+ }
109+ }
110+
111+ // 3. Filter by name "Connect"
112+ const connectKeys = allKeys . filter ( key => key . name === ConnectApiKeyService . CONNECT_API_KEY_NAME ) ;
113+
114+ // 4. Find keys with correct description vs incorrect description
115+ const correctKeys = connectKeys . filter ( key => key . description === targetDescription ) ;
116+ const incorrectKeys = connectKeys . filter ( key => key . description !== targetDescription ) ;
117+
118+ // 5. Delete keys with incorrect description
119+ if ( incorrectKeys . length > 0 ) {
120+ const idsToDelete = incorrectKeys . map ( key => key . id ) ;
121+ await this . deleteApiKeys ( idsToDelete ) ;
122+ this . logger . log ( `Deleted ${ incorrectKeys . length } Connect API keys with incorrect descriptions` ) ;
94123 }
95- // 2. Check disk
96- const localApiKeyFromDisk = this . apiKeyService . findByField ( 'name' , 'Connect' ) ;
97- if ( localApiKeyFromDisk ) {
98- return localApiKeyFromDisk . key ;
124+
125+ // 6. If we have a correct key, return it
126+ if ( correctKeys . length > 0 ) {
127+ const correctKeyWithSecret = this . findByIdWithSecret ( correctKeys [ 0 ] . id ) ;
128+ if ( correctKeyWithSecret ) {
129+ return correctKeyWithSecret . key ;
130+ }
99131 }
100- // 3. If no key found, create one
101- const localApiKey = await this . createLocalConnectApiKey ( ) ;
132+
133+ // 7. Create a new key with the correct description
134+ const localApiKey = await this . create ( {
135+ name : ConnectApiKeyService . CONNECT_API_KEY_NAME ,
136+ description : targetDescription ,
137+ roles : [ Role . CONNECT ] ,
138+ overwrite : true ,
139+ } ) ;
140+
102141 if ( ! localApiKey ?. key ) {
103142 throw new Error ( 'Failed to create local API key' ) ;
104143 }
144+
105145 return localApiKey . key ;
106146 }
107147}
0 commit comments