mirror of
https://github.com/unraid/api.git
synced 2025-12-31 05:29:48 -06:00
fix: delete legacy connect keys and ensure description
This commit is contained in:
@@ -12,6 +12,8 @@ import { ConnectConfigService } from './connect-config.service.js';
|
||||
export class ConnectApiKeyService implements ApiKeyService {
|
||||
private readonly logger = new Logger(ConnectApiKeyService.name);
|
||||
private static readonly validRoles: Set<Role> = new Set(Object.values(Role));
|
||||
private static readonly CONNECT_API_KEY_NAME = 'Connect';
|
||||
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';
|
||||
|
||||
constructor(
|
||||
@Inject(API_KEY_SERVICE_TOKEN)
|
||||
@@ -72,11 +74,13 @@ export class ConnectApiKeyService implements ApiKeyService {
|
||||
public async createLocalConnectApiKey(): Promise<ApiKeyWithSecret | null> {
|
||||
try {
|
||||
return await this.create({
|
||||
name: 'Connect',
|
||||
name: ConnectApiKeyService.CONNECT_API_KEY_NAME,
|
||||
description: 'API key for Connect user',
|
||||
roles: [Role.CONNECT],
|
||||
overwrite: true,
|
||||
});
|
||||
|
||||
// Delete all other API keys with the role CONNECT
|
||||
} catch (err) {
|
||||
this.logger.error(`Failed to create local API key for Connect user: ${err}`);
|
||||
return null;
|
||||
@@ -87,21 +91,57 @@ export class ConnectApiKeyService implements ApiKeyService {
|
||||
* Gets or creates a local API key for Connect
|
||||
*/
|
||||
public async getOrCreateLocalApiKey(): Promise<string> {
|
||||
// 1. Check in-memory config
|
||||
const targetDescription = ConnectApiKeyService.CONNECT_API_KEY_DESCRIPTION;
|
||||
|
||||
// 1. Get all API keys first
|
||||
const allKeys = await this.findAll();
|
||||
|
||||
// 2. Check in-memory config and verify key exists
|
||||
const { localApiKey: localApiKeyFromConfig } = this.connectConfig.getConfig();
|
||||
if (localApiKeyFromConfig && localApiKeyFromConfig !== '') {
|
||||
return localApiKeyFromConfig;
|
||||
const keyExists = allKeys.some(key => {
|
||||
const keyWithSecret = this.findByIdWithSecret(key.id);
|
||||
return keyWithSecret?.key === localApiKeyFromConfig;
|
||||
});
|
||||
if (keyExists) {
|
||||
return localApiKeyFromConfig;
|
||||
}
|
||||
}
|
||||
// 2. Check disk
|
||||
const localApiKeyFromDisk = this.apiKeyService.findByField('name', 'Connect');
|
||||
if (localApiKeyFromDisk) {
|
||||
return localApiKeyFromDisk.key;
|
||||
|
||||
// 3. Filter by name "Connect"
|
||||
const connectKeys = allKeys.filter(key => key.name === ConnectApiKeyService.CONNECT_API_KEY_NAME);
|
||||
|
||||
// 4. Find keys with correct description vs incorrect description
|
||||
const correctKeys = connectKeys.filter(key => key.description === targetDescription);
|
||||
const incorrectKeys = connectKeys.filter(key => key.description !== targetDescription);
|
||||
|
||||
// 5. Delete keys with incorrect description
|
||||
if (incorrectKeys.length > 0) {
|
||||
const idsToDelete = incorrectKeys.map(key => key.id);
|
||||
await this.deleteApiKeys(idsToDelete);
|
||||
this.logger.log(`Deleted ${incorrectKeys.length} Connect API keys with incorrect descriptions`);
|
||||
}
|
||||
// 3. If no key found, create one
|
||||
const localApiKey = await this.createLocalConnectApiKey();
|
||||
|
||||
// 6. If we have a correct key, return it
|
||||
if (correctKeys.length > 0) {
|
||||
const correctKeyWithSecret = this.findByIdWithSecret(correctKeys[0].id);
|
||||
if (correctKeyWithSecret) {
|
||||
return correctKeyWithSecret.key;
|
||||
}
|
||||
}
|
||||
|
||||
// 7. Create a new key with the correct description
|
||||
const localApiKey = await this.create({
|
||||
name: ConnectApiKeyService.CONNECT_API_KEY_NAME,
|
||||
description: targetDescription,
|
||||
roles: [Role.CONNECT],
|
||||
overwrite: true,
|
||||
});
|
||||
|
||||
if (!localApiKey?.key) {
|
||||
throw new Error('Failed to create local API key');
|
||||
}
|
||||
|
||||
return localApiKey.key;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,11 +180,9 @@ async function upsertKey() {
|
||||
const apiKeyResult = res?.data?.apiKey;
|
||||
if (isEdit && apiKeyResult && 'update' in apiKeyResult) {
|
||||
const fragmentData = useFragment(API_KEY_FRAGMENT_WITH_KEY, apiKeyResult.update);
|
||||
console.log('fragmentData', fragmentData);
|
||||
apiKeyStore.setCreatedKey(fragmentData);
|
||||
} else if (!isEdit && apiKeyResult && 'create' in apiKeyResult) {
|
||||
const fragmentData = useFragment(API_KEY_FRAGMENT_WITH_KEY, apiKeyResult.create);
|
||||
console.log('fragmentData', fragmentData);
|
||||
apiKeyStore.setCreatedKey(fragmentData);
|
||||
}
|
||||
|
||||
@@ -262,7 +260,7 @@ async function upsertKey() {
|
||||
areAllPermissionsSelected() ? clearAllPermissions() : selectAllPermissions()
|
||||
"
|
||||
>
|
||||
{{ areAllPermissionsSelected() ? 'Select None' : 'Select All' }}
|
||||
{{ areAllPermissionsSelected() ? 'Clear All' : 'Select All' }}
|
||||
</Button>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2 mt-1">
|
||||
@@ -283,7 +281,7 @@ async function upsertKey() {
|
||||
: selectAllActions(perm.resource)
|
||||
"
|
||||
>
|
||||
{{ areAllActionsSelected(perm.resource) ? 'Select None' : 'Select All' }}
|
||||
{{ areAllActionsSelected(perm.resource) ? 'Clear All' : 'Select All' }}
|
||||
</Button>
|
||||
</div>
|
||||
<div class="flex gap-4 flex-wrap">
|
||||
|
||||
Reference in New Issue
Block a user